/*
 * Copyright (C) 2017 Thomas Wolf <thomas.wolf@paranor.ch> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.ignore;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.filter.NotIgnoredFilter;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FS.ExecutionResult;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests that verify that the set of ignore files in a repository is the same in
 * JGit and in C-git.
 */
public class CGitIgnoreTest extends RepositoryTestCase {

	@Before
	public void initRepo() throws IOException {
		// These tests focus on .gitignore files inside the repository. Because
		// we run C-git, we must ensure that global or user exclude files cannot
		// influence the tests. So we set core.excludesFile to an empty file
		// inside the repository.
		File fakeUserGitignore = writeTrashFile(".fake_user_gitignore", "");
		StoredConfig config = db.getConfig();
		config.setString("core", null, "excludesFile",
				fakeUserGitignore.getAbsolutePath());
		// Disable case-insensitivity -- JGit doesn't handle that yet.
		config.setBoolean("core", null, "ignoreCase", false);
		config.save();
	}

	private void createFiles(String... paths) throws IOException {
		for (String path : paths) {
			writeTrashFile(path, "x");
		}
	}

	private String toString(TemporaryBuffer b) throws IOException {
		return RawParseUtils.decode(b.toByteArray());
	}

	private String[] cgitIgnored() throws Exception {
		FS fs = db.getFS();
		ProcessBuilder builder = fs.runInShell("git", new String[] { "ls-files",
				"--ignored", "--exclude-standard", "-o" });
		builder.directory(db.getWorkTree());
		builder.environment().put("HOME", fs.userHome().getAbsolutePath());
		ExecutionResult result = fs.execute(builder,
				new ByteArrayInputStream(new byte[0]));
		String errorOut = toString(result.getStderr());
		assertEquals("External git failed", "exit 0\n",
				"exit " + result.getRc() + '\n' + errorOut);
		try (BufferedReader r = new BufferedReader(new InputStreamReader(
				new BufferedInputStream(result.getStdout().openInputStream()),
				UTF_8))) {
			return r.lines().toArray(String[]::new);
		}
	}

	private String[] cgitUntracked() throws Exception {
		FS fs = db.getFS();
		ProcessBuilder builder = fs.runInShell("git",
				new String[] { "ls-files", "--exclude-standard", "-o" });
		builder.directory(db.getWorkTree());
		builder.environment().put("HOME", fs.userHome().getAbsolutePath());
		ExecutionResult result = fs.execute(builder,
				new ByteArrayInputStream(new byte[0]));
		String errorOut = toString(result.getStderr());
		assertEquals("External git failed", "exit 0\n",
				"exit " + result.getRc() + '\n' + errorOut);
		try (BufferedReader r = new BufferedReader(new InputStreamReader(
				new BufferedInputStream(result.getStdout().openInputStream()),
				UTF_8))) {
			return r.lines().toArray(String[]::new);
		}
	}

	private void jgitIgnoredAndUntracked(LinkedHashSet<String> ignored,
			LinkedHashSet<String> untracked) throws IOException {
		// Do a tree walk that does descend into ignored directories and return
		// a list of all ignored files
		try (TreeWalk walk = new TreeWalk(db)) {
			FileTreeIterator iter = new FileTreeIterator(db);
			iter.setWalkIgnoredDirectories(true);
			walk.addTree(iter);
			walk.setRecursive(true);
			while (walk.next()) {
				if (walk.getTree(WorkingTreeIterator.class).isEntryIgnored()) {
					ignored.add(walk.getPathString());
				} else {
					// tests of this class won't add any files to the index,
					// hence everything what is not ignored is untracked
					untracked.add(walk.getPathString());
				}
			}
		}
	}

	private void assertNoIgnoredVisited(Set<String> ignored) throws Exception {
		// Do a recursive tree walk with a NotIgnoredFilter and verify that none
		// of the files visited is in the ignored set
		try (TreeWalk walk = new TreeWalk(db)) {
			walk.addTree(new FileTreeIterator(db));
			walk.setFilter(new NotIgnoredFilter(0));
			walk.setRecursive(true);
			while (walk.next()) {
				String path = walk.getPathString();
				assertFalse("File " + path + " is ignored, should not appear",
						ignored.contains(path));
			}
		}
	}

	private void assertSameAsCGit(String... notIgnored) throws Exception {
		LinkedHashSet<String> ignored = new LinkedHashSet<>();
		LinkedHashSet<String> untracked = new LinkedHashSet<>();
		jgitIgnoredAndUntracked(ignored, untracked);
		String[] cgit = cgitIgnored();
		String[] cgitUntracked = cgitUntracked();
		assertArrayEquals(cgit, ignored.toArray());
		assertArrayEquals(cgitUntracked, untracked.toArray());
		for (String notExcluded : notIgnored) {
			assertFalse("File " + notExcluded + " should not be ignored",
					ignored.contains(notExcluded));
		}
		assertNoIgnoredVisited(ignored);
	}

	@Test
	public void testSimpleIgnored() throws Exception {
		createFiles("a.txt", "a.tmp", "src/sub/a.txt", "src/a.tmp",
				"src/a.txt/b.tmp", "ignored/a.tmp", "ignored/not_ignored/a.tmp",
				"ignored/other/a.tmp");
		writeTrashFile(".gitignore",
				"*.txt\n" + "/ignored/*\n" + "!/ignored/not_ignored");
		assertSameAsCGit("ignored/not_ignored/a.tmp");
	}

	@Test
	public void testDirOnlyMatch() throws Exception {
		createFiles("a.txt", "src/foo/a.txt", "src/a.txt", "foo/a.txt");
		writeTrashFile(".gitignore", "foo/");
		assertSameAsCGit();
	}

	@Test
	public void testDirOnlyMatchDeep() throws Exception {
		createFiles("a.txt", "src/foo/a.txt", "src/a.txt", "foo/a.txt");
		writeTrashFile(".gitignore", "**/foo/");
		assertSameAsCGit();
	}

	@Test
	public void testStarMatchOnSlashNot() throws Exception {
		createFiles("sub/a.txt", "foo/sext", "foo/s.txt");
		writeTrashFile(".gitignore", "s*xt");
		assertSameAsCGit("sub/a.txt");
	}

	@Test
	public void testPrefixMatch() throws Exception {
		createFiles("src/new/foo.txt");
		writeTrashFile(".gitignore", "src/new");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryMatchSubRecursive() throws Exception {
		createFiles("src/new/foo.txt", "foo/src/new/foo.txt", "sub/src/new");
		writeTrashFile(".gitignore", "**/src/new/");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryMatchSubRecursiveBacktrack() throws Exception {
		createFiles("src/new/foo.txt", "src/src/new/foo.txt");
		writeTrashFile(".gitignore", "**/src/new/");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryMatchSubRecursiveBacktrack2() throws Exception {
		createFiles("src/new/foo.txt", "src/src/new/foo.txt");
		writeTrashFile(".gitignore", "**/**/src/new/");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryMatchSubRecursiveBacktrack3() throws Exception {
		createFiles("x/a/a/b/foo.txt");
		writeTrashFile(".gitignore", "**/*/a/b/");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryMatchSubRecursiveBacktrack4() throws Exception {
		createFiles("x/a/a/b/foo.txt", "x/y/z/b/a/b/foo.txt",
				"x/y/a/a/a/a/b/foo.txt", "x/y/a/a/a/a/b/a/b/foo.txt");
		writeTrashFile(".gitignore", "**/*/a/b bar\n");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryMatchSubRecursiveBacktrack5() throws Exception {
		createFiles("x/a/a/b/foo.txt", "x/y/a/b/a/b/foo.txt");
		writeTrashFile(".gitignore", "**/*/**/a/b bar\n");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryWildmatchDoesNotMatchFiles1() throws Exception {
		createFiles("a", "dir/b", "dir/sub/c");
		writeTrashFile(".gitignore", "**/\n");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryWildmatchDoesNotMatchFiles2() throws Exception {
		createFiles("a", "dir/b", "dir/sub/c");
		writeTrashFile(".gitignore", "**/**/\n");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryWildmatchDoesNotMatchFiles3() throws Exception {
		createFiles("a", "x/b", "sub/x/c", "sub/x/d/e");
		writeTrashFile(".gitignore", "x/**/\n");
		assertSameAsCGit();
	}

	@Test
	public void testDirectoryWildmatchDoesNotMatchFiles4() throws Exception {
		createFiles("a", "dir/x", "dir/sub1/x", "dir/sub2/x/y");
		writeTrashFile(".gitignore", "**/x/\n");
		assertSameAsCGit();
	}

	@Test
	public void testUnescapedBracketsInGroup() throws Exception {
		createFiles("[", "]", "[]", "][", "[[]", "[]]", "[[]]");
		writeTrashFile(".gitignore", "[[]]\n");
		assertSameAsCGit();
	}

	@Test
	public void testEscapedFirstBracketInGroup() throws Exception {
		createFiles("[", "]", "[]", "][", "[[]", "[]]", "[[]]");
		writeTrashFile(".gitignore", "[\\[]]\n");
		assertSameAsCGit();
	}

	@Test
	public void testEscapedSecondBracketInGroup() throws Exception {
		createFiles("[", "]", "[]", "][", "[[]", "[]]", "[[]]");
		writeTrashFile(".gitignore", "[[\\]]\n");
		assertSameAsCGit();
	}

	@Test
	public void testEscapedBothBracketsInGroup() throws Exception {
		createFiles("[", "]", "[]", "][", "[[]", "[]]", "[[]]");
		writeTrashFile(".gitignore", "[\\[\\]]\n");
		assertSameAsCGit();
	}

	@Test
	public void testSimpleRootGitIgnoreGlobalNegation1() throws Exception {
		// see IgnoreNodeTest.testSimpleRootGitIgnoreGlobalNegation1
		createFiles("x1", "a/x2", "x3/y");
		writeTrashFile(".gitignore", "*\n!x*");
		assertSameAsCGit();
	}

	@Test
	public void testRepeatedNegationInDifferentFiles5() throws Exception {
		// see IgnoreNodeTest.testRepeatedNegationInDifferentFiles5
		createFiles("a/b/e/nothere.o");
		writeTrashFile(".gitignore", "e");
		writeTrashFile("a/.gitignore", "e");
		writeTrashFile("a/b/.gitignore", "!e");
		assertSameAsCGit();
	}

	@Test
	public void testRepeatedNegationInDifferentFilesWithWildmatcher1()
			throws Exception {
		createFiles("e", "x/e/f", "a/e/x1", "a/e/x2", "a/e/y", "a/e/sub/y");
		writeTrashFile(".gitignore", "a/e/**");
		writeTrashFile("a/.gitignore", "!e/x*");
		assertSameAsCGit();
	}

	@Test
	public void testRepeatedNegationInDifferentFilesWithWildmatcher2()
			throws Exception {
		createFiles("e", "dir/f", "dir/g/h", "a/dir/i", "a/dir/j/k",
				"a/b/dir/l", "a/b/dir/m/n", "a/b/dir/m/o/p", "a/q/dir/r",
				"a/q/dir/dir/s", "c/d/dir/x", "c/d/dir/y");
		writeTrashFile(".gitignore", "**/dir/*");
		writeTrashFile("a/.gitignore", "!dir/*");
		writeTrashFile("a/b/.gitignore", "!**/dir/*");
		writeTrashFile("c/.gitignore", "!d/dir/x");
		assertSameAsCGit();
	}

	@Test
	public void testNegationForSubDirectoryWithinIgnoredDirectoryHasNoEffect1()
			throws Exception {
		createFiles("e", "a/f", "a/b/g", "a/b/h/i");
		writeTrashFile(".gitignore", "a/b");
		writeTrashFile("a/.gitignore", "!b/*");
		assertSameAsCGit();
	}

	/*
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=407475
	 */
	@Test
	public void testNegationAllExceptJavaInSrcAndExceptChildDirInSrc()
			throws Exception {
		// see
		// IgnoreNodeTest.testNegationAllExceptJavaInSrcAndExceptChildDirInSrc
		createFiles("nothere.o", "src/keep.java", "src/nothere.o",
				"src/a/keep.java", "src/a/keep.o");
		writeTrashFile(".gitignore", "/*\n!/src/");
		writeTrashFile("src/.gitignore", "*\n!*.java\n!*/");
		assertSameAsCGit();
	}
}
