/*
 * Copyright (C) 2011, Abhishek Bhatnagar <abhatnag@redhat.com> 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.api;

import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoFilepatternException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests for CleanCommand
 */
public class CleanCommandTest extends RepositoryTestCase {
	private Git git;

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		git = new Git(db);

		// create test files
		writeTrashFile("File1.txt", "Hello world");
		writeTrashFile("File2.txt", "Delete Me");
		writeTrashFile("File3.txt", "Delete Me");

		// create files in sub-directories.
		writeTrashFile("sub-noclean/File1.txt", "Hello world");
		writeTrashFile("sub-noclean/File2.txt", "Delete Me");
		writeTrashFile("sub-clean/File4.txt", "Delete Me");
		writeTrashFile("sub-noclean/Ignored.txt", "Ignored");
		writeTrashFile(".gitignore", "/ignored-dir\n/sub-noclean/Ignored.txt");
		writeTrashFile("ignored-dir/Ignored2.txt", "Ignored");

		// add and commit first file
		git.add().addFilepattern("File1.txt").call();
		git.add().addFilepattern("sub-noclean/File1.txt").call();
		git.add().addFilepattern(".gitignore").call();
		git.commit().setMessage("Initial commit").call();
	}

	@Test
	public void testClean() throws NoWorkTreeException, GitAPIException {
		// create status
		StatusCommand command = git.status();
		Status status = command.call();
		Set<String> files = status.getUntracked();
		assertFalse(files.isEmpty());

		// run clean
		Set<String> cleanedFiles = git.clean().call();

		status = git.status().call();
		files = status.getUntracked();

		assertTrue(files.size() == 1); // one remains (directories not cleaned)
		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
		assertTrue(!cleanedFiles.contains("sub-clean/File4.txt"));
	}

	@Test
	public void testCleanDirs() throws NoWorkTreeException, GitAPIException {
		// create status
		StatusCommand command = git.status();
		Status status = command.call();
		Set<String> files = status.getUntracked();
		assertFalse(files.isEmpty());

		// run clean
		Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();

		status = git.status().call();
		files = status.getUntracked();

		assertTrue(files.isEmpty());
		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
		assertTrue(cleanedFiles.contains("sub-clean/"));
	}

	@Test
	public void testCleanWithPaths() throws NoWorkTreeException,
			GitAPIException {
		// create status
		StatusCommand command = git.status();
		Status status = command.call();
		Set<String> files = status.getUntracked();
		assertFalse(files.isEmpty());

		// run clean with setPaths
		Set<String> paths = new TreeSet<>();
		paths.add("File3.txt");
		Set<String> cleanedFiles = git.clean().setPaths(paths).call();

		status = git.status().call();
		files = status.getUntracked();
		assertTrue(files.size() == 3);
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertFalse(cleanedFiles.contains("File2.txt"));
	}

	@Test
	public void testCleanWithDryRun() throws NoWorkTreeException,
			GitAPIException {
		// create status
		StatusCommand command = git.status();
		Status status = command.call();
		Set<String> files = status.getUntracked();
		assertFalse(files.isEmpty());

		// run clean
		Set<String> cleanedFiles = git.clean().setDryRun(true).call();

		status = git.status().call();
		files = status.getUntracked();

		assertEquals(4, files.size());
		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
	}

	@Test
	public void testCleanDirsWithDryRun() throws NoWorkTreeException,
			GitAPIException {
		// create status
		StatusCommand command = git.status();
		Status status = command.call();
		Set<String> files = status.getUntracked();
		assertFalse(files.isEmpty());

		// run clean
		Set<String> cleanedFiles = git.clean().setDryRun(true)
				.setCleanDirectories(true).call();

		status = git.status().call();
		files = status.getUntracked();

		assertTrue(files.size() == 4);
		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
		assertTrue(cleanedFiles.contains("sub-clean/"));
	}

	@Test
	public void testCleanWithDryRunAndNoIgnore() throws NoWorkTreeException,
			GitAPIException {
		// run clean
		Set<String> cleanedFiles = git.clean().setDryRun(true).setIgnore(false)
				.call();

		Status status = git.status().call();
		Set<String> files = status.getIgnoredNotInIndex();

		assertTrue(files.size() == 2);
		assertTrue(cleanedFiles.contains("sub-noclean/Ignored.txt"));
		assertTrue(!cleanedFiles.contains("ignored-dir/"));
	}

	@Test
	public void testCleanDirsWithDryRunAndNoIgnore()
			throws NoWorkTreeException, GitAPIException {
		// run clean
		Set<String> cleanedFiles = git.clean().setDryRun(true).setIgnore(false)
				.setCleanDirectories(true).call();

		Status status = git.status().call();
		Set<String> files = status.getIgnoredNotInIndex();

		assertTrue(files.size() == 2);
		assertTrue(cleanedFiles.contains("sub-noclean/Ignored.txt"));
		assertTrue(cleanedFiles.contains("ignored-dir/"));
	}

	@Test
	public void testCleanDirsWithPrefixFolder() throws Exception {
		String path = "sub/foo.txt";
		writeTrashFile(path, "sub is a prefix of sub-noclean");
		git.add().addFilepattern(path).call();
		Status beforeCleanStatus = git.status().call();
		assertTrue(beforeCleanStatus.getAdded().contains(path));

		Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();

		// The "sub" directory should not be cleaned.
		assertTrue(!cleanedFiles.contains(path + "/"));

		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
		assertTrue(cleanedFiles.contains("sub-clean/"));
		assertTrue(cleanedFiles.size() == 4);
	}

	@Test
	public void testCleanDirsWithSubmodule() throws Exception {
		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
		String path = "sub";
		command.setPath(path);
		String uri = db.getDirectory().toURI().toString();
		command.setURI(uri);
		try (Repository repo = command.call()) {
			// Unused
		}

		Status beforeCleanStatus = git.status().call();
		assertTrue(beforeCleanStatus.getAdded().contains(DOT_GIT_MODULES));
		assertTrue(beforeCleanStatus.getAdded().contains(path));

		Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();

		// The submodule should not be cleaned.
		assertTrue(!cleanedFiles.contains(path + "/"));

		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
		assertTrue(cleanedFiles.contains("sub-clean/"));
		assertTrue(cleanedFiles.size() == 4);
	}

	@Test
	public void testCleanDirsWithRepository() throws Exception {
		// Set up a repository inside the outer repository
		String innerRepoName = "inner-repo";
		File innerDir = new File(trash, innerRepoName);
		innerDir.mkdir();
		InitCommand initRepoCommand = new InitCommand();
		initRepoCommand.setDirectory(innerDir);
		initRepoCommand.call();

		Status beforeCleanStatus = git.status().call();
		Set<String> untrackedFolders = beforeCleanStatus.getUntrackedFolders();
		Set<String> untrackedFiles = beforeCleanStatus.getUntracked();

		// The inner repository should be listed as an untracked file
		assertTrue(untrackedFiles.contains(innerRepoName));

		// The inner repository should not be listed as an untracked folder
		assertTrue(!untrackedFolders.contains(innerRepoName));

		Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();

		// The inner repository should not be cleaned.
		assertTrue(!cleanedFiles.contains(innerRepoName + "/"));

		assertTrue(cleanedFiles.contains("File2.txt"));
		assertTrue(cleanedFiles.contains("File3.txt"));
		assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
		assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
		assertTrue(cleanedFiles.contains("sub-clean/"));
		assertTrue(cleanedFiles.size() == 4);

		Set<String> forceCleanedFiles = git.clean().setCleanDirectories(true)
				.setForce(true).call();

		// The inner repository should be cleaned this time
		assertTrue(forceCleanedFiles.contains(innerRepoName + "/"));
	}

	@Test
	// To proof Bug 514434. No assertions, but before the bugfix
	// this test was throwing Exceptions
	public void testFilesShouldBeCleanedInSubSubFolders()
			throws IOException, NoFilepatternException, GitAPIException {
		writeTrashFile(".gitignore",
				"/ignored-dir\n/sub-noclean/Ignored.txt\n/this_is_ok\n/this_is/not_ok\n");
		git.add().addFilepattern(".gitignore").call();
		git.commit().setMessage("adding .gitignore").call();
		writeTrashFile("this_is_ok/more/subdirs/file.txt", "1");
		writeTrashFile("this_is/not_ok/more/subdirs/file.txt", "2");
		git.clean().setCleanDirectories(true).setIgnore(false).call();
	}
}
