/*
 * Copyright (C) 2015, Andrei Pozolotin.
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.transport;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.cryptoCipherListPBE;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.cryptoCipherListTrans;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.folderDelete;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.permitLongTests;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.policySetup;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.product;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.proxySetup;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.publicAddress;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.reportPolicy;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.securityProviderName;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.textWrite;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.transferStream;
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.verifyFileContent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;

import javax.crypto.SecretKeyFactory;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
import org.eclipse.jgit.util.FileUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Suite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Amazon S3 encryption pipeline test.
 *
 * See {@link AmazonS3} {@link WalkEncryption}
 *
 * Note: CI server must provide amazon credentials (access key, secret key,
 * bucket name) via one of methods available in {@link Names}.
 *
 * Note: long running tests are activated by Maven profile "test.long". There is
 * also a separate Eclipse m2e launcher for that. See 'pom.xml' and
 * 'WalkEncryptionTest.launch'.
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({ //
		WalkEncryptionTest.Required.class, //
		WalkEncryptionTest.MinimalSet.class, //
		WalkEncryptionTest.TestablePBE.class, //
		WalkEncryptionTest.TestableTransformation.class, //
})
public class WalkEncryptionTest {

	/**
	 * Logger setup: ${project_loc}/tst-rsrc/log4j.properties
	 */
	static final Logger logger = LoggerFactory.getLogger(WalkEncryptionTest.class);

	/**
	 * Property names used in test session.
	 */
	interface Names {

		// Names of discovered test properties.

		String TEST_BUCKET = "test.bucket";

		// Names of test environment variables for CI.

		String ENV_ACCESS_KEY = "JGIT_S3_ACCESS_KEY";

		String ENV_SECRET_KEY = "JGIT_S3_SECRET_KEY";

		String ENV_BUCKET_NAME = "JGIT_S3_BUCKET_NAME";

		// Name of test environment variable file path for CI.

		String ENV_CONFIG_FILE = "JGIT_S3_CONFIG_FILE";

		// Names of test system properties for CI.

		String SYS_ACCESS_KEY = "jgit.s3.access.key";

		String SYS_SECRET_KEY = "jgit.s3.secret.key";

		String SYS_BUCKET_NAME = "jgit.s3.bucket.name";

		// Name of test system property file path for CI.
		String SYS_CONFIG_FILE = "jgit.s3.config.file";

		// Hard coded name of test properties file for CI.
		// File format follows AmazonS3.Keys:
		// #
		// # Required entries:
		// #
		// accesskey = your-amazon-access-key # default AmazonS3.Keys
		// secretkey = your-amazon-secret-key # default AmazonS3.Keys
		// test.bucket = your-bucket-for-testing # custom name, for this test
		String CONFIG_FILE = "jgit-s3-config.properties";

		// Test properties file in [user home] of CI.
		String HOME_CONFIG_FILE = System.getProperty("user.home")
				+ File.separator + CONFIG_FILE;

		// Test properties file in [project work directory] of CI.
		String WORK_CONFIG_FILE = System.getProperty("user.dir")
				+ File.separator + CONFIG_FILE;

		// Test properties file in [project test source directory] of CI.
		String TEST_CONFIG_FILE = System.getProperty("user.dir")
				+ File.separator + "tst-rsrc" + File.separator + CONFIG_FILE;

	}

	/**
	 * Find test properties from various sources in order of priority.
	 */
	static class Props implements WalkEncryptionTest.Names, AmazonS3.Keys {

		static boolean haveEnvVar(String name) {
			return System.getenv(name) != null;
		}

		static boolean haveEnvVarFile(String name) {
			return haveEnvVar(name) && new File(name).exists();
		}

		static boolean haveSysProp(String name) {
			return System.getProperty(name) != null;
		}

		static boolean haveSysPropFile(String name) {
			return haveSysProp(name) && new File(name).exists();
		}

		static void loadEnvVar(String source, String target, Properties props) {
			props.put(target, System.getenv(source));
		}

		static void loadSysProp(String source, String target,
				Properties props) {
			props.put(target, System.getProperty(source));
		}

		static boolean haveProp(String name, Properties props) {
			return props.containsKey(name);
		}

		static boolean checkTestProps(Properties props) {
			return haveProp(ACCESS_KEY, props) && haveProp(SECRET_KEY, props)
					&& haveProp(TEST_BUCKET, props);
		}

		static Properties fromEnvVars() {
			if (haveEnvVar(ENV_ACCESS_KEY) && haveEnvVar(ENV_SECRET_KEY)
					&& haveEnvVar(ENV_BUCKET_NAME)) {
				Properties props = new Properties();
				loadEnvVar(ENV_ACCESS_KEY, ACCESS_KEY, props);
				loadEnvVar(ENV_SECRET_KEY, SECRET_KEY, props);
				loadEnvVar(ENV_BUCKET_NAME, TEST_BUCKET, props);
				return props;
			}
			return null;
		}

		static Properties fromEnvFile() throws Exception {
			if (haveEnvVarFile(ENV_CONFIG_FILE)) {
				Properties props = new Properties();
				props.load(new FileInputStream(ENV_CONFIG_FILE));
				if (checkTestProps(props)) {
					return props;
				}
				throw new Error("Environment config file is incomplete.");
			}
			return null;
		}

		static Properties fromSysProps() {
			if (haveSysProp(SYS_ACCESS_KEY) && haveSysProp(SYS_SECRET_KEY)
					&& haveSysProp(SYS_BUCKET_NAME)) {
				Properties props = new Properties();
				loadSysProp(SYS_ACCESS_KEY, ACCESS_KEY, props);
				loadSysProp(SYS_SECRET_KEY, SECRET_KEY, props);
				loadSysProp(SYS_BUCKET_NAME, TEST_BUCKET, props);
				return props;
			}
			return null;
		}

		static Properties fromSysFile() throws Exception {
			if (haveSysPropFile(SYS_CONFIG_FILE)) {
				Properties props = new Properties();
				props.load(new FileInputStream(SYS_CONFIG_FILE));
				if (checkTestProps(props)) {
					return props;
				}
				throw new Error("System props config file is incomplete.");
			}
			return null;
		}

		static Properties fromConfigFile(String path) throws Exception {
			File file = new File(path);
			if (file.exists()) {
				Properties props = new Properties();
				props.load(new FileInputStream(file));
				if (checkTestProps(props)) {
					return props;
				}
				throw new Error("Props config file is incomplete: " + path);
			}
			return null;
		}

		/**
		 * Find test properties from various sources in order of priority.
		 *
		 * @return result
		 * @throws Exception
		 */
		static Properties discover() throws Exception {
			Properties props;
			if ((props = fromEnvVars()) != null) {
				logger.debug(
						"Using test properties from environment variables.");
				return props;
			}
			if ((props = fromEnvFile()) != null) {
				logger.debug(
						"Using test properties from environment variable config file.");
				return props;
			}
			if ((props = fromSysProps()) != null) {
				logger.debug("Using test properties from system properties.");
				return props;
			}
			if ((props = fromSysFile()) != null) {
				logger.debug(
						"Using test properties from system property config file.");
				return props;
			}
			if ((props = fromConfigFile(HOME_CONFIG_FILE)) != null) {
				logger.debug(
						"Using test properties from hard coded ${user.home} file.");
				return props;
			}
			if ((props = fromConfigFile(WORK_CONFIG_FILE)) != null) {
				logger.debug(
						"Using test properties from hard coded ${user.dir} file.");
				return props;
			}
			if ((props = fromConfigFile(TEST_CONFIG_FILE)) != null) {
				logger.debug(
						"Using test properties from hard coded ${project.source} file.");
				return props;
			}
			throw new Error("Can not load test properties form any source.");
		}

	}

	/**
	 * Collection of test utility methods.
	 */
	static class Util {

		/**
		 * Read UTF-8 encoded text file into string.
		 *
		 * @param file
		 * @return result
		 * @throws Exception
		 */
		static String textRead(File file) throws Exception {
			return new String(Files.readAllBytes(file.toPath()), UTF_8);
		}

		/**
		 * Write string into UTF-8 encoded file.
		 *
		 * @param file
		 * @param text
		 * @throws Exception
		 */
		static void textWrite(File file, String text) throws Exception {
			Files.write(file.toPath(), text.getBytes(UTF_8));
		}

		static void verifyFileContent(File fileOne, File fileTwo)
				throws Exception {
			assertTrue(fileOne.length() > 0);
			assertTrue(fileTwo.length() > 0);
			String textOne = textRead(fileOne);
			String textTwo = textRead(fileTwo);
			assertEquals(textOne, textTwo);
		}

		/**
		 * Create local folder.
		 *
		 * @param folder
		 * @throws Exception
		 */
		static void folderCreate(String folder) throws Exception {
			File path = new File(folder);
			assertTrue(path.mkdirs());
		}

		/**
		 * Delete local folder.
		 *
		 * @param folder
		 * @throws Exception
		 */
		static void folderDelete(String folder) throws Exception {
			File path = new File(folder);
			FileUtils.delete(path,
					FileUtils.RECURSIVE | FileUtils.SKIP_MISSING);
		}

		/**
		 * Discover public address of CI server.
		 *
		 * @return result
		 * @throws Exception
		 */
		static String publicAddress() throws Exception {
			try {
				String service = "http://checkip.amazonaws.com";
				URL url = new URL(service);
				URLConnection c = url.openConnection();
				c.setConnectTimeout(500);
				c.setReadTimeout(500);
				try (BufferedReader reader = new BufferedReader(
						new InputStreamReader(c.getInputStream(), UTF_8))) {
					return reader.readLine();
				}
			} catch (UnknownHostException | SocketTimeoutException e) {
				return "Can't reach http://checkip.amazonaws.com to"
						+ " determine public address";
			}
		}

		/**
		 * Discover Password-Based Encryption (PBE) engines providing both
		 * [SecretKeyFactory] and [AlgorithmParameters].
		 *
		 * @return result
		 */
		// https://www.bouncycastle.org/specifications.html
		// https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html
		static List<String> cryptoCipherListPBE() {
			return cryptoCipherList(WalkEncryption.Vals.REGEX_PBE);
		}

		// TODO returns inconsistent list.
		static List<String> cryptoCipherListTrans() {
			return cryptoCipherList(WalkEncryption.Vals.REGEX_TRANS);
		}

		static String securityProviderName(String algorithm) throws Exception {
			return SecretKeyFactory.getInstance(algorithm).getProvider()
					.getName();
		}

		static List<String> cryptoCipherList(String regex) {
			Set<String> source = Security.getAlgorithms("Cipher");
			Set<String> target = new TreeSet<>();
			for (String algo : source) {
				algo = algo.toUpperCase(Locale.ROOT);
				if (algo.matches(regex)) {
					target.add(algo);
				}
			}
			return new ArrayList<>(target);
		}

		/**
		 * Stream copy.
		 *
		 * @param from
		 * @param into
		 * @return count
		 * @throws IOException
		 */
		static long transferStream(InputStream from, OutputStream into)
				throws IOException {
			byte[] array = new byte[1 * 1024];
			long total = 0;
			while (true) {
				int count = from.read(array);
				if (count == -1) {
					break;
				}
				into.write(array, 0, count);
				total += count;
			}
			return total;
		}

		/**
		 * Setup proxy during CI build.
		 *
		 * @throws Exception
		 */
		// https://wiki.eclipse.org/Hudson#Accessing_the_Internet_using_Proxy
		// http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
		static void proxySetup() throws Exception {
			String keyNoProxy = "no_proxy";
			String keyHttpProxy = "http_proxy";
			String keyHttpsProxy = "https_proxy";

			String no_proxy = System.getProperty(keyNoProxy,
					System.getenv(keyNoProxy));
			if (no_proxy != null) {
				System.setProperty("http.nonProxyHosts", no_proxy);
				logger.info("Proxy NOT: " + no_proxy);
			}

			String http_proxy = System.getProperty(keyHttpProxy,
					System.getenv(keyHttpProxy));
			if (http_proxy != null) {
				URL url = new URL(http_proxy);
				System.setProperty("http.proxyHost", url.getHost());
				System.setProperty("http.proxyPort", "" + url.getPort());
				logger.info("Proxy HTTP: " + http_proxy);
			}

			String https_proxy = System.getProperty(keyHttpsProxy,
					System.getenv(keyHttpsProxy));
			if (https_proxy != null) {
				URL url = new URL(https_proxy);
				System.setProperty("https.proxyHost", url.getHost());
				System.setProperty("https.proxyPort", "" + url.getPort());
				logger.info("Proxy HTTPS: " + https_proxy);
			}

			if (no_proxy == null && http_proxy == null && https_proxy == null) {
				logger.info("Proxy not used.");
			}

		}

		/**
		 * Permit long tests on CI or with manual activation.
		 *
		 * @return result
		 */
		static boolean permitLongTests() {
			return isBuildCI() || isProfileActive();
		}

		/**
		 * Using Maven profile activation, see pom.xml
		 *
		 * @return result
		 */
		static boolean isProfileActive() {
			return Boolean.parseBoolean(System.getProperty("jgit.test.long"));
		}

		/**
		 * Detect if build is running on CI.
		 *
		 * @return result
		 */
		static boolean isBuildCI() {
			return System.getenv("HUDSON_HOME") != null;
		}

		/**
		 * Setup JCE security policy restrictions. Can remove restrictions when
		 * restrictions are present, but can not impose them when restrictions
		 * are missing.
		 *
		 * @param restrictedOn
		 */
		// http://www.docjar.com/html/api/javax/crypto/JceSecurity.java.html
		static void policySetup(boolean restrictedOn) {
			try {
				java.lang.reflect.Field isRestricted = Class
						.forName("javax.crypto.JceSecurity")
						.getDeclaredField("isRestricted");
				isRestricted.setAccessible(true);
				isRestricted.set(null, Boolean.valueOf(restrictedOn));
			} catch (Throwable e) {
				logger.info(
						"Could not setup JCE security policy restrictions.");
			}
		}

		static void reportPolicy() {
			try {
				java.lang.reflect.Field isRestricted = Class
						.forName("javax.crypto.JceSecurity")
						.getDeclaredField("isRestricted");
				isRestricted.setAccessible(true);
				logger.info("JCE security policy restricted="
						+ isRestricted.get(null));
			} catch (Throwable e) {
				logger.info(
						"Could not report JCE security policy restrictions.");
			}
		}

		static List<Object[]> product(List<String> one, List<String> two) {
			List<Object[]> result = new ArrayList<>();
			for (String s1 : one) {
				for (String s2 : two) {
					result.add(new Object[] { s1, s2 });
				}
			}
			return result;
		}

	}

	/**
	 * Common base for encryption tests.
	 */
	@FixMethodOrder(MethodSorters.NAME_ASCENDING)
	public abstract static class Base extends SampleDataRepositoryTestCase {

		/**
		 * S3 URI user used by JGIT to discover connection configuration file.
		 */
		static final String JGIT_USER = "tester-" + System.currentTimeMillis();

		/**
		 * S3 content encoding password used for this test session.
		 */
		static final String JGIT_PASS = "secret-" + System.currentTimeMillis();

		/**
		 * S3 repository configuration file expected by {@link AmazonS3}.
		 */
		static final String JGIT_CONF_FILE = System.getProperty("user.home")
				+ "/" + JGIT_USER;

		/**
		 * Name representing remote or local JGIT repository.
		 */
		static final String JGIT_REPO_DIR = JGIT_USER + ".jgit";

		/**
		 * Local JGIT repository for this test session.
		 */
		static final String JGIT_LOCAL_DIR = System.getProperty("user.dir")
				+ "/target/" + JGIT_REPO_DIR;

		/**
		 * Remote JGIT repository for this test session.
		 */
		static final String JGIT_REMOTE_DIR = JGIT_REPO_DIR;

		/**
		 * Generate JGIT S3 connection configuration file.
		 *
		 * @param algorithm
		 * @throws Exception
		 */
		static void configCreate(String algorithm) throws Exception {
			Properties props = Props.discover();
			props.put(AmazonS3.Keys.PASSWORD, JGIT_PASS);
			props.put(AmazonS3.Keys.CRYPTO_ALG, algorithm);
			try (PrintWriter writer = new PrintWriter(JGIT_CONF_FILE,
					UTF_8.name())) {
				props.store(writer, "JGIT S3 connection configuration file.");
			}
		}

		/**
		 * Generate JGIT S3 connection configuration file.
		 *
		 * @param source
		 * @throws Exception
		 */
		static void configCreate(Properties source) throws Exception {
			Properties target = Props.discover();
			target.putAll(source);
			try (PrintWriter writer = new PrintWriter(JGIT_CONF_FILE,
					UTF_8.name())) {
				target.store(writer, "JGIT S3 connection configuration file.");
			}
		}

		/**
		 * Remove JGIT connection configuration file.
		 *
		 * @throws Exception
		 */
		static void configDelete() throws Exception {
			File path = new File(JGIT_CONF_FILE);
			FileUtils.delete(path, FileUtils.SKIP_MISSING);
		}

		/**
		 * Generate remote URI for the test session.
		 *
		 * @return result
		 * @throws Exception
		 */
		static String amazonURI() throws Exception {
			Properties props = Props.discover();
			String bucket = props.getProperty(Names.TEST_BUCKET);
			assertNotNull(bucket);
			return TransportAmazonS3.S3_SCHEME + "://" + JGIT_USER + "@"
					+ bucket + "/" + JGIT_REPO_DIR;
		}

		/**
		 * Create S3 repository folder.
		 *
		 * @throws Exception
		 */
		static void remoteCreate() throws Exception {
			Properties props = Props.discover();
			props.remove(AmazonS3.Keys.PASSWORD); // Disable encryption.
			String bucket = props.getProperty(Names.TEST_BUCKET);
			AmazonS3 s3 = new AmazonS3(props);
			String path = JGIT_REMOTE_DIR + "/";
			s3.put(bucket, path, new byte[0]);
			logger.debug("remote create: " + JGIT_REMOTE_DIR);
		}

		/**
		 * Delete S3 repository folder.
		 *
		 * @throws Exception
		 */
		static void remoteDelete() throws Exception {
			Properties props = Props.discover();
			props.remove(AmazonS3.Keys.PASSWORD); // Disable encryption.
			String bucket = props.getProperty(Names.TEST_BUCKET);
			AmazonS3 s3 = new AmazonS3(props);
			List<String> list = s3.list(bucket, JGIT_REMOTE_DIR);
			for (String path : list) {
				path = JGIT_REMOTE_DIR + "/" + path;
				s3.delete(bucket, path);
			}
			logger.debug("remote delete: " + JGIT_REMOTE_DIR);
		}

		/**
		 * Verify if we can create/delete remote file.
		 *
		 * @throws Exception
		 */
		static void remoteVerify() throws Exception {
			Properties props = Props.discover();
			String bucket = props.getProperty(Names.TEST_BUCKET);
			AmazonS3 s3 = new AmazonS3(props);
			String file = JGIT_USER + "-" + UUID.randomUUID().toString();
			String path = JGIT_REMOTE_DIR + "/" + file;
			s3.put(bucket, path, file.getBytes(UTF_8));
			s3.delete(bucket, path);
		}

		/**
		 * Verify if any security provider published the algorithm.
		 *
		 * @param algorithm
		 * @return result
		 */
		static boolean isAlgorithmPresent(String algorithm) {
			Set<String> cipherSet = Security.getAlgorithms("Cipher");
			for (String source : cipherSet) {
				// Standard names are not case-sensitive.
				// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
				String target = algorithm.toUpperCase(Locale.ROOT);
				if (source.equalsIgnoreCase(target)) {
					return true;
				}
			}
			return false;
		}

		static boolean isAlgorithmPresent(Properties props) {
			String profile = props.getProperty(AmazonS3.Keys.CRYPTO_ALG);
			String version = props.getProperty(AmazonS3.Keys.CRYPTO_VER,
					WalkEncryption.Vals.DEFAULT_VERS);
			String cryptoAlgo;
			String keyAlgo;
			switch (version) {
			case WalkEncryption.Vals.DEFAULT_VERS:
			case WalkEncryption.JGitV1.VERSION:
				cryptoAlgo = profile;
				keyAlgo = profile;
				break;
			case WalkEncryption.JGitV2.VERSION:
				cryptoAlgo = props
						.getProperty(profile + WalkEncryption.Keys.X_ALGO);
				keyAlgo = props
						.getProperty(profile + WalkEncryption.Keys.X_KEY_ALGO);
				break;
			default:
				return false;
			}
			try {
				InsecureCipherFactory.create(cryptoAlgo);
				SecretKeyFactory.getInstance(keyAlgo);
				return true;
			} catch (Throwable e) {
				return false;
			}
		}

		/**
		 * Verify if JRE security policy allows the algorithm.
		 *
		 * @param algorithm
		 * @return result
		 */
		static boolean isAlgorithmAllowed(String algorithm) {
			try {
				WalkEncryption crypto = new WalkEncryption.JetS3tV2(
						algorithm, JGIT_PASS);
				verifyCrypto(crypto);
				return true;
			} catch (IOException e) {
				return false; // Encryption failure.
			} catch (GeneralSecurityException e) {
				throw new Error(e); // Construction failure.
			}
		}

		static boolean isAlgorithmAllowed(Properties props) {
			try {
				WalkEncryption.instance(props);
				return true;
			} catch (GeneralSecurityException e) {
				return false;
			}
		}

		/**
		 * Verify round trip encryption.
		 *
		 * @param crypto
		 * @throws IOException
		 */
		static void verifyCrypto(WalkEncryption crypto) throws IOException {
			String charset = "UTF-8";
			String sourceText = "secret-message Свобода 老子";
			String targetText;
			byte[] cipherText;
			{
				byte[] origin = sourceText.getBytes(charset);
				ByteArrayOutputStream target = new ByteArrayOutputStream();
				try (OutputStream source = crypto.encrypt(target)) {
					source.write(origin);
					source.flush();
				}
				cipherText = target.toByteArray();
			}
			{
				InputStream source = new ByteArrayInputStream(cipherText);
				InputStream target = crypto.decrypt(source);
				ByteArrayOutputStream result = new ByteArrayOutputStream();
				transferStream(target, result);
				targetText = result.toString(charset);
			}
			assertEquals(sourceText, targetText);
		}

		/**
		 * Algorithm is testable when it is present and allowed by policy.
		 *
		 * @param algorithm
		 * @return result
		 */
		static boolean isAlgorithmTestable(String algorithm) {
			return isAlgorithmPresent(algorithm)
					&& isAlgorithmAllowed(algorithm);
		}

		static boolean isAlgorithmTestable(Properties props) {
			return isAlgorithmPresent(props) && isAlgorithmAllowed(props);
		}

		/**
		 * Log algorithm, provider, testability.
		 *
		 * @param algorithm
		 * @throws Exception
		 */
		static void reportAlgorithmStatus(String algorithm) throws Exception {
			final boolean present = isAlgorithmPresent(algorithm);
			final boolean allowed = present && isAlgorithmAllowed(algorithm);
			final String provider = present ? securityProviderName(algorithm)
					: "N/A";
			String status = "Algorithm: " + algorithm + " @ " + provider + "; "
					+ "present/allowed : " + present + "/" + allowed;
			if (allowed) {
				logger.info("Testing " + status);
			} else {
				logger.warn("Missing " + status);
			}
		}

		static void reportAlgorithmStatus(Properties props) throws Exception {
			final boolean present = isAlgorithmPresent(props);
			final boolean allowed = present && isAlgorithmAllowed(props);

			String profile = props.getProperty(AmazonS3.Keys.CRYPTO_ALG);
			String version = props.getProperty(AmazonS3.Keys.CRYPTO_VER);

			StringBuilder status = new StringBuilder();
			status.append(" Version: " + version);
			status.append(" Profile: " + profile);
			status.append(" Present: " + present);
			status.append(" Allowed: " + allowed);

			if (allowed) {
				logger.info("Testing " + status);
			} else {
				logger.warn("Missing " + status);
			}
		}

		/**
		 * Verify if we can perform remote tests.
		 *
		 * @return result
		 */
		static boolean isTestConfigPresent() {
			try {
				Props.discover();
				return true;
			} catch (Throwable e) {
				return false;
			}
		}

		static void reportTestConfigPresent() {
			if (isTestConfigPresent()) {
				logger.info("Amazon S3 test configuration is present.");
			} else {
				logger.error(
						"Amazon S3 test configuration is missing, tests will not run.");
			}
		}

		/**
		 * Log public address of CI.
		 *
		 * @throws Exception
		 */
		static void reportPublicAddress() throws Exception {
			logger.info("Public address: " + publicAddress());
		}

		/**
		 * BouncyCastle provider class.
		 *
		 * Needs extra dependency, see pom.xml
		 */
		// http://search.maven.org/#artifactdetails%7Corg.bouncycastle%7Cbcprov-jdk15on%7C1.52%7Cjar
		static final String PROVIDER_BC = "org.bouncycastle.jce.provider.BouncyCastleProvider";

		/**
		 * Load BouncyCastle provider if present.
		 */
		static void loadBouncyCastle() {
			try {
				Class<?> provider = Class.forName(PROVIDER_BC);
				Provider instance = (Provider) provider
						.getConstructor(new Class[] {})
						.newInstance(new Object[] {});
				Security.addProvider(instance);
				logger.info("Loaded " + PROVIDER_BC);
			} catch (Throwable e) {
				logger.warn("Failed to load " + PROVIDER_BC);
			}
		}

		static void reportLongTests() {
			if (permitLongTests()) {
				logger.info("Long running tests are enabled.");
			} else {
				logger.warn("Long running tests are disabled.");
			}
		}

		/**
		 * Non-PBE algorithm, for error check.
		 */
		static final String ALGO_ERROR = "PBKDF2WithHmacSHA1";

		/**
		 * Default JetS3t algorithm present in most JRE.
		 */
		static final String ALGO_JETS3T = "PBEWithMD5AndDES";

		/**
		 * Minimal strength AES based algorithm present in most JRE.
		 */
		static final String ALGO_MINIMAL_AES = "PBEWithHmacSHA1AndAES_128";

		/**
		 * Selected non-AES algorithm present in BouncyCastle provider.
		 */
		static final String ALGO_BOUNCY_CASTLE_CBC = "PBEWithSHAAndTwofish-CBC";

		//////////////////////////////////////////////////

		@BeforeClass
		public static void initialize() throws Exception {
			Transport.register(TransportAmazonS3.PROTO_S3);
			proxySetup();
			reportPolicy();
			reportLongTests();
			reportPublicAddress();
			reportTestConfigPresent();
			loadBouncyCastle();
			if (isTestConfigPresent()) {
				remoteCreate();
			}
		}

		@AfterClass
		public static void terminate() throws Exception {
			configDelete();
			folderDelete(JGIT_LOCAL_DIR);
			if (isTestConfigPresent()) {
				remoteDelete();
			}
		}

		@Before
		@Override
		public void setUp() throws Exception {
			super.setUp();
		}

		@After
		@Override
		public void tearDown() throws Exception {
			super.tearDown();
		}

		/**
		 * Optional encrypted amazon remote JGIT life cycle test.
		 *
		 * @param props
		 * @throws Exception
		 */
		void cryptoTestIfCan(Properties props) throws Exception {
			reportAlgorithmStatus(props);
			assumeTrue(isTestConfigPresent());
			assumeTrue(isAlgorithmTestable(props));
			cryptoTest(props);
		}

		/**
		 * Required encrypted amazon remote JGIT life cycle test.
		 *
		 * @param props
		 * @throws Exception
		 */
		void cryptoTest(Properties props) throws Exception {

			remoteDelete();
			configCreate(props);
			folderDelete(JGIT_LOCAL_DIR);

			String uri = amazonURI();

			// Local repositories.
			File dirOne = db.getWorkTree(); // Provided by setup.
			File dirTwo = new File(JGIT_LOCAL_DIR);

			// Local verification files.
			String nameStatic = "master.txt"; // Provided by setup.
			String nameDynamic = JGIT_USER + "-" + UUID.randomUUID().toString();

			String remote = "remote";
			RefSpec specs = new RefSpec("refs/heads/master:refs/heads/master");

			{ // Push into remote from local one.

				StoredConfig config = db.getConfig();
				RemoteConfig remoteConfig = new RemoteConfig(config, remote);
				remoteConfig.addURI(new URIish(uri));
				remoteConfig.update(config);
				config.save();

				try (Git git = Git.open(dirOne)) {
					git.checkout().setName("master").call();
					git.push().setRemote(remote).setRefSpecs(specs).call();
				}

				File fileStatic = new File(dirOne, nameStatic);
				assertTrue("Provided by setup", fileStatic.exists());

			}

			{ // Clone from remote into local two.

				File fileStatic = new File(dirTwo, nameStatic);
				assertFalse("Not Provided by setup", fileStatic.exists());

				try (Git git = Git.cloneRepository().setURI(uri)
						.setDirectory(dirTwo).call()) {
					assertTrue("Provided by clone", fileStatic.exists());
				}

			}

			{ // Verify static file content.
				File fileOne = new File(dirOne, nameStatic);
				File fileTwo = new File(dirTwo, nameStatic);
				verifyFileContent(fileOne, fileTwo);
			}

			{ // Verify new file commit and push from local one.

				File fileDynamic = new File(dirOne, nameDynamic);
				assertFalse("Not Provided by setup", fileDynamic.exists());
				FileUtils.createNewFile(fileDynamic);
				textWrite(fileDynamic, nameDynamic);
				assertTrue("Provided by create", fileDynamic.exists());
				assertTrue("Need content to encrypt", fileDynamic.length() > 0);

				try (Git git = Git.open(dirOne)) {
					git.add().addFilepattern(nameDynamic).call();
					git.commit().setMessage(nameDynamic).call();
					git.push().setRemote(remote).setRefSpecs(specs).call();
				}

			}

			{ // Verify new file pull from remote into local two.

				File fileDynamic = new File(dirTwo, nameDynamic);
				assertFalse("Not Provided by setup", fileDynamic.exists());

				try (Git git = Git.open(dirTwo)) {
					git.pull().call();
				}

				assertTrue("Provided by pull", fileDynamic.exists());
			}

			{ // Verify dynamic file content.
				File fileOne = new File(dirOne, nameDynamic);
				File fileTwo = new File(dirTwo, nameDynamic);
				verifyFileContent(fileOne, fileTwo);
			}

		}

	}

	/**
	 * Verify prerequisites.
	 */
	@FixMethodOrder(MethodSorters.NAME_ASCENDING)
	public static class Required extends Base {

		@Test
		public void test_A1_ValidURI() throws Exception {
			assumeTrue(isTestConfigPresent());
			URIish uri = new URIish(amazonURI());
			assertTrue("uri=" + uri, TransportAmazonS3.PROTO_S3.canHandle(uri));
		}

		@Test(expected = Exception.class)
		public void test_A2_CryptoError() throws Exception {
			assumeTrue(isTestConfigPresent());
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, ALGO_ERROR);
			props.put(AmazonS3.Keys.PASSWORD, JGIT_PASS);
			cryptoTest(props);
		}

	}

	/**
	 * Test minimal set of algorithms.
	 */
	@FixMethodOrder(MethodSorters.NAME_ASCENDING)
	public static class MinimalSet extends Base {

		@Test
		public void test_V0_Java7_JET() throws Exception {
			assumeTrue(isTestConfigPresent());
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, ALGO_JETS3T);
			// Do not set version.
			props.put(AmazonS3.Keys.PASSWORD, JGIT_PASS);
			cryptoTestIfCan(props);
		}

		@Test
		public void test_V1_Java7_GIT() throws Exception {
			assumeTrue(isTestConfigPresent());
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, ALGO_JETS3T);
			props.put(AmazonS3.Keys.CRYPTO_VER, "1");
			props.put(AmazonS3.Keys.PASSWORD, JGIT_PASS);
			cryptoTestIfCan(props);
		}

		@Test
		public void test_V2_Java7_AES() throws Exception {
			assumeTrue(isTestConfigPresent());
			// String profile = "default";
			String profile = "AES/CBC/PKCS5Padding+PBKDF2WithHmacSHA1";
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, profile);
			props.put(AmazonS3.Keys.CRYPTO_VER, "2");
			props.put(AmazonS3.Keys.PASSWORD, JGIT_PASS);
			props.put(profile + WalkEncryption.Keys.X_ALGO, "AES/CBC/PKCS5Padding");
			props.put(profile + WalkEncryption.Keys.X_KEY_ALGO, "PBKDF2WithHmacSHA1");
			props.put(profile + WalkEncryption.Keys.X_KEY_SIZE, "128");
			props.put(profile + WalkEncryption.Keys.X_KEY_ITER, "10000");
			props.put(profile + WalkEncryption.Keys.X_KEY_SALT, "e2 55 89 67 8e 8d e8 4c");
			cryptoTestIfCan(props);
		}

		@Test
		public void test_V2_Java8_PBE_AES() throws Exception {
			assumeTrue(isTestConfigPresent());
			String profile = "PBEWithHmacSHA512AndAES_256";
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, profile);
			props.put(AmazonS3.Keys.CRYPTO_VER, "2");
			props.put(AmazonS3.Keys.PASSWORD, JGIT_PASS);
			props.put(profile + WalkEncryption.Keys.X_ALGO, "PBEWithHmacSHA512AndAES_256");
			props.put(profile + WalkEncryption.Keys.X_KEY_ALGO, "PBEWithHmacSHA512AndAES_256");
			props.put(profile + WalkEncryption.Keys.X_KEY_SIZE, "256");
			props.put(profile + WalkEncryption.Keys.X_KEY_ITER, "10000");
			props.put(profile + WalkEncryption.Keys.X_KEY_SALT, "e2 55 89 67 8e 8d e8 4c");
			policySetup(false);
			cryptoTestIfCan(props);
		}

	}

	/**
	 * Test all present and allowed PBE algorithms.
	 */
	// https://github.com/junit-team/junit/wiki/Parameterized-tests
	@RunWith(Parameterized.class)
	@FixMethodOrder(MethodSorters.NAME_ASCENDING)
	public static class TestablePBE extends Base {

		@Parameters(name = "Profile: {0}   Version: {1}")
		public static Collection<Object[]> argsList() {
			List<String> algorithmList = new ArrayList<>();
			algorithmList.addAll(cryptoCipherListPBE());

			List<String> versionList = new ArrayList<>();
			versionList.add("0");
			versionList.add("1");

			return product(algorithmList, versionList);
		}

		final String profile;

		final String version;

		final String password = JGIT_PASS;

		public TestablePBE(String profile, String version) {
			this.profile = profile;
			this.version = version;
		}

		@Test
		public void testCrypto() throws Exception {
			assumeTrue(permitLongTests());
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, profile);
			props.put(AmazonS3.Keys.CRYPTO_VER, version);
			props.put(AmazonS3.Keys.PASSWORD, password);
			cryptoTestIfCan(props);
		}

	}

	/**
	 * Test all present and allowed transformation algorithms.
	 */
	// https://github.com/junit-team/junit/wiki/Parameterized-tests
	@RunWith(Parameterized.class)
	@FixMethodOrder(MethodSorters.NAME_ASCENDING)
	public static class TestableTransformation extends Base {

		@Parameters(name = "Profile: {0}   Version: {1}")
		public static Collection<Object[]> argsList() {
			List<String> algorithmList = new ArrayList<>();
			algorithmList.addAll(cryptoCipherListTrans());

			List<String> versionList = new ArrayList<>();
			versionList.add("1");

			return product(algorithmList, versionList);
		}

		final String profile;

		final String version;

		final String password = JGIT_PASS;

		public TestableTransformation(String profile, String version) {
			this.profile = profile;
			this.version = version;
		}

		@Test
		public void testCrypto() throws Exception {
			assumeTrue(permitLongTests());
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, profile);
			props.put(AmazonS3.Keys.CRYPTO_VER, version);
			props.put(AmazonS3.Keys.PASSWORD, password);
			cryptoTestIfCan(props);
		}

	}

}
