/*
 * Copyright (C) 2015, Sebastien Arod <sebastien.arod@gmail.com>
 * 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.ignore;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.util.FileUtils;
import org.junit.Assert;
import org.junit.Test;

/**
 * This test generates random ignore patterns and random path and compares the
 * output of Cgit check-ignore to the output of {@link FastIgnoreRule}.
 */
public class CGitVsJGitRandomIgnorePatternTest {

	private static class PseudoRandomPatternGenerator {

		private static final int DEFAULT_MAX_FRAGMENTS_PER_PATTERN = 15;

		/**
		 * Generates 75% Special fragments and 25% "standard" characters
		 */
		private static final double DEFAULT_SPECIAL_FRAGMENTS_FREQUENCY = 0.75d;

		private static final List<String> SPECIAL_FRAGMENTS = Arrays.asList(
				"\\", "!", "#", "[", "]", "|", "/", "*", "?", "{", "}", "(",
				")", "\\d", "(", "**", "[a\\]]", "\\ ", "+", "-", "^", "$", ".",
				":", "=", "[[:", ":]]"

		);

		private static final String STANDARD_CHARACTERS = new String(
				"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");

		private final Random random = new Random();

		private final int maxFragmentsPerPattern;

		private final double specialFragmentsFrequency;

		public PseudoRandomPatternGenerator() {
			this(DEFAULT_MAX_FRAGMENTS_PER_PATTERN,
					DEFAULT_SPECIAL_FRAGMENTS_FREQUENCY);
		}

		public PseudoRandomPatternGenerator(int maxFragmentsPerPattern,
				double specialFragmentsFrequency) {
			this.maxFragmentsPerPattern = maxFragmentsPerPattern;
			this.specialFragmentsFrequency = specialFragmentsFrequency;
		}

		public String nextRandomString() {
			StringBuilder builder = new StringBuilder();
			int length = randomFragmentCount();
			for (int i = 0; i < length; i++) {
				if (useSpecialFragment()) {
					builder.append(randomSpecialFragment());
				} else {
					builder.append(randomStandardCharacters());
				}

			}
			return builder.toString();
		}

		private int randomFragmentCount() {
			// We want at least one fragment
			return 1 + random.nextInt(maxFragmentsPerPattern - 1);
		}

		private char randomStandardCharacters() {
			return STANDARD_CHARACTERS
					.charAt(random.nextInt(STANDARD_CHARACTERS.length()));
		}

		private boolean useSpecialFragment() {
			return random.nextDouble() < specialFragmentsFrequency;
		}

		private String randomSpecialFragment() {
			return SPECIAL_FRAGMENTS
					.get(random.nextInt(SPECIAL_FRAGMENTS.size()));
		}
	}

	@SuppressWarnings("serial")
	public static class CgitFatalException extends Exception {

		public CgitFatalException(int cgitExitCode, String pattern, String path,
				String cgitStdError) {
			super("CgitFatalException (" + cgitExitCode + ") for pattern:["
					+ pattern + "] and path:[" + path + "]\n" + cgitStdError);
		}

	}

	public static class CGitIgnoreRule {

		private File gitDir;

		private String pattern;

		public CGitIgnoreRule(File gitDir, String pattern) throws IOException {
			this.gitDir = gitDir;
			this.pattern = pattern;
			Files.write(FileUtils.toPath(new File(gitDir, ".gitignore")),
					(pattern + "\n").getBytes(UTF_8), StandardOpenOption.CREATE,
					StandardOpenOption.TRUNCATE_EXISTING,
					StandardOpenOption.WRITE);
		}

		public boolean isMatch(String path)
				throws IOException, InterruptedException, CgitFatalException {
			Process proc = startCgitCheckIgnore(path);

			String cgitStdOutput = readProcessStream(proc.getInputStream());
			String cgitStdError = readProcessStream(proc.getErrorStream());

			int cgitExitCode = proc.waitFor();

			if (cgitExitCode == 128) {
				throw new CgitFatalException(cgitExitCode, pattern, path,
						cgitStdError);
			}
			return !cgitStdOutput.startsWith("::");
		}

		private Process startCgitCheckIgnore(String path) throws IOException {
			// Use --stdin instead of using argument otherwise paths starting
			// with "-" were interpreted as
			// options by git check-ignore
			String[] command = new String[] { "git", "check-ignore",
					"--no-index", "-v", "-n", "--stdin" };
			Process proc = Runtime.getRuntime().exec(command, new String[0],
					gitDir);
			OutputStream out = proc.getOutputStream();
			out.write((path + "\n").getBytes(UTF_8));
			out.flush();
			out.close();
			return proc;
		}

		private String readProcessStream(InputStream processStream)
				throws IOException {
			try (BufferedReader stdOut = new BufferedReader(
					new InputStreamReader(processStream))) {

				StringBuilder out = new StringBuilder();
				String s;
				while ((s = stdOut.readLine()) != null) {
					out.append(s);
				}
				return out.toString();
			}
		}
	}

	private static final int NB_PATTERN = 1000;

	private static final int PATH_PER_PATTERN = 1000;

	@Test
	public void testRandomPatterns() throws Exception {
		// Initialize new git repo
		File gitDir = Files.createTempDirectory("jgit").toFile();
		Git.init().setDirectory(gitDir).call();
		PseudoRandomPatternGenerator generator = new PseudoRandomPatternGenerator();

		// Generate random patterns and paths
		for (int i = 0; i < NB_PATTERN; i++) {
			String pattern = generator.nextRandomString();

			FastIgnoreRule jgitIgnoreRule = new FastIgnoreRule(pattern);
			CGitIgnoreRule cgitIgnoreRule = new CGitIgnoreRule(gitDir, pattern);

			// Test path with pattern as path
			assertCgitAndJgitMatch(pattern, jgitIgnoreRule, cgitIgnoreRule,
					pattern);

			for (int p = 0; p < PATH_PER_PATTERN; p++) {
				String path = generator.nextRandomString();
				assertCgitAndJgitMatch(pattern, jgitIgnoreRule, cgitIgnoreRule,
						path);
			}
		}
	}

	@SuppressWarnings({ "boxing" })
	private void assertCgitAndJgitMatch(String pattern,
			FastIgnoreRule jgitIgnoreRule, CGitIgnoreRule cgitIgnoreRule,
			String pathToTest) throws IOException, InterruptedException {

		try {
			boolean cgitMatch = cgitIgnoreRule.isMatch(pathToTest);
			boolean jgitMatch = jgitIgnoreRule.isMatch(pathToTest,
					pathToTest.endsWith("/"));
			if (cgitMatch != jgitMatch) {
				System.err.println(
						buildAssertionToAdd(pattern, pathToTest, cgitMatch));
			}
			Assert.assertEquals("jgit:" + jgitMatch + " <> cgit:" + cgitMatch
					+ " for pattern:[" + pattern + "] and path:[" + pathToTest
					+ "]", cgitMatch, jgitMatch);
		} catch (CgitFatalException e) {
			// Lots of generated patterns or path are rejected by Cgit with a
			// fatal error. We want to ignore them.
		}
	}

	private String buildAssertionToAdd(String pattern, String pathToTest,
			boolean cgitMatch) {
		return "assertMatch(" + toJavaString(pattern) + ", "
				+ toJavaString(pathToTest) + ", " + cgitMatch
				+ " /*cgit result*/);";
	}

	private String toJavaString(String pattern2) {
		return "\"" + pattern2.replace("\\", "\\\\").replace("\"", "\\\"")
				+ "\"";
	}
}
