/*
 * Copyright (C) 2010, 2013 Matthias Sohn <matthias.sohn@sap.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.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.rmi.RemoteException;
import java.util.regex.Matcher;

import javax.management.remote.JMXProviderException;

import org.eclipse.jgit.junit.JGitTestUtil;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;

public class FileUtilsTest {
	private static final String MSG = "Stale file handle";

	private static final String SOME_ERROR_MSG = "some error message";

	private static final IOException IO_EXCEPTION = new UnsupportedEncodingException(
			MSG);

	private static final IOException IO_EXCEPTION_WITH_CAUSE = new RemoteException(
			SOME_ERROR_MSG,
			new JMXProviderException(SOME_ERROR_MSG, IO_EXCEPTION));

	private File trash;

	@Before
	public void setUp() throws Exception {
		trash = File.createTempFile("tmp_", "");
		trash.delete();
		assertTrue("mkdir " + trash, trash.mkdir());
	}

	@After
	public void tearDown() throws Exception {
		FileUtils.delete(trash, FileUtils.RECURSIVE | FileUtils.RETRY);
	}

	@Test
	public void testDeleteFile() throws IOException {
		File f = new File(trash, "test");
		FileUtils.createNewFile(f);
		FileUtils.delete(f);
		assertFalse(f.exists());

		try {
			FileUtils.delete(f);
			fail("deletion of non-existing file must fail");
		} catch (IOException e) {
			// expected
		}

		try {
			FileUtils.delete(f, FileUtils.SKIP_MISSING);
		} catch (IOException e) {
			fail("deletion of non-existing file must not fail with option SKIP_MISSING");
		}
	}

	@Test
	public void testDeleteRecursive() throws IOException {
		File f1 = new File(trash, "test/test/a");
		FileUtils.mkdirs(f1.getParentFile());
		FileUtils.createNewFile(f1);
		File f2 = new File(trash, "test/test/b");
		FileUtils.createNewFile(f2);
		File d = new File(trash, "test");
		FileUtils.delete(d, FileUtils.RECURSIVE);
		assertFalse(d.exists());

		try {
			FileUtils.delete(d, FileUtils.RECURSIVE);
			fail("recursive deletion of non-existing directory must fail");
		} catch (IOException e) {
			// expected
		}

		try {
			FileUtils.delete(d, FileUtils.RECURSIVE | FileUtils.SKIP_MISSING);
		} catch (IOException e) {
			fail("recursive deletion of non-existing directory must not fail with option SKIP_MISSING");
		}
	}

	@Test

	public void testDeleteRecursiveEmpty() throws IOException {
		File f1 = new File(trash, "test/test/a");
		File f2 = new File(trash, "test/a");
		File d1 = new File(trash, "test");
		File d2 = new File(trash, "test/test");
		File d3 = new File(trash, "test/b");
		FileUtils.mkdirs(f1.getParentFile());
		FileUtils.createNewFile(f2);
		FileUtils.createNewFile(f1);
		FileUtils.mkdirs(d3);

		// Cannot delete hierarchy since files exist
		try {
			FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY);
			fail("delete should fail");
		} catch (IOException e1) {
			try {
				FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY|FileUtils.RECURSIVE);
				fail("delete should fail");
			} catch (IOException e2) {
				// Everything still there
				assertTrue(f1.exists());
				assertTrue(f2.exists());
				assertTrue(d1.exists());
				assertTrue(d2.exists());
				assertTrue(d3.exists());
			}
		}

		// setup: delete files, only directories left
		assertTrue(f1.delete());
		assertTrue(f2.delete());

		// Shall not delete hierarchy without recursive
		try {
			FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY);
			fail("delete should fail");
		} catch (IOException e2) {
			// Everything still there
			assertTrue(d1.exists());
			assertTrue(d2.exists());
			assertTrue(d3.exists());
		}

		// Now delete the empty hierarchy
		FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
				| FileUtils.RECURSIVE);
		assertFalse(d2.exists());

		// Will fail to delete non-existing without SKIP_MISSING
		try {
			FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY);
			fail("Cannot delete non-existent entity");
		} catch (IOException e) {
			// ok
		}

		// ..with SKIP_MISSING there is no exception
		FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
				| FileUtils.SKIP_MISSING);
		FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
				| FileUtils.RECURSIVE | FileUtils.SKIP_MISSING);

		// essentially the same, using IGNORE_ERRORS
		FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
				| FileUtils.IGNORE_ERRORS);
		FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
				| FileUtils.RECURSIVE | FileUtils.IGNORE_ERRORS);
	}

	@Test
	public void testDeleteRecursiveEmptyNeedsToCheckFilesFirst()
			throws IOException {
		File d1 = new File(trash, "test");
		File d2 = new File(trash, "test/a");
		File d3 = new File(trash, "test/b");
		File f1 = new File(trash, "test/c");
		File d4 = new File(trash, "test/d");
		FileUtils.mkdirs(d1);
		FileUtils.mkdirs(d2);
		FileUtils.mkdirs(d3);
		FileUtils.mkdirs(d4);
		FileUtils.createNewFile(f1);

		// Cannot delete hierarchy since file exists
		try {
			FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY
					| FileUtils.RECURSIVE);
			fail("delete should fail");
		} catch (IOException e) {
			// Everything still there
			assertTrue(f1.exists());
			assertTrue(d1.exists());
			assertTrue(d2.exists());
			assertTrue(d3.exists());
			assertTrue(d4.exists());
		}
	}

	@Test
	public void testDeleteRecursiveEmptyDirectoriesOnlyButIsFile()
			throws IOException {
		File f1 = new File(trash, "test/test/a");
		FileUtils.mkdirs(f1.getParentFile());
		FileUtils.createNewFile(f1);
		try {
			FileUtils.delete(f1, FileUtils.EMPTY_DIRECTORIES_ONLY);
			fail("delete should fail");
		} catch (IOException e) {
			assertTrue(f1.exists());
		}
	}

	@Test
	public void testMkdir() throws IOException {
		File d = new File(trash, "test");
		FileUtils.mkdir(d);
		assertTrue(d.exists() && d.isDirectory());

		try {
			FileUtils.mkdir(d);
			fail("creation of existing directory must fail");
		} catch (IOException e) {
			// expected
		}

		FileUtils.mkdir(d, true);
		assertTrue(d.exists() && d.isDirectory());

		assertTrue(d.delete());
		File f = new File(trash, "test");
		FileUtils.createNewFile(f);
		try {
			FileUtils.mkdir(d);
			fail("creation of directory having same path as existing file must"
					+ " fail");
		} catch (IOException e) {
			// expected
		}
		assertTrue(f.delete());
	}

	@Test
	public void testMkdirs() throws IOException {
		File root = new File(trash, "test");
		assertTrue(root.mkdir());

		File d = new File(root, "test/test");
		FileUtils.mkdirs(d);
		assertTrue(d.exists() && d.isDirectory());

		try {
			FileUtils.mkdirs(d);
			fail("creation of existing directory hierarchy must fail");
		} catch (IOException e) {
			// expected
		}

		FileUtils.mkdirs(d, true);
		assertTrue(d.exists() && d.isDirectory());

		FileUtils.delete(root, FileUtils.RECURSIVE);
		File f = new File(trash, "test");
		FileUtils.createNewFile(f);
		try {
			FileUtils.mkdirs(d);
			fail("creation of directory having path conflicting with existing"
					+ " file must fail");
		} catch (IOException e) {
			// expected
		}
		assertTrue(f.delete());
	}

	@Test
	public void testCreateNewFile() throws IOException {
		File f = new File(trash, "x");
		FileUtils.createNewFile(f);
		assertTrue(f.exists());

		try {
			FileUtils.createNewFile(f);
			fail("creation of already existing file must fail");
		} catch (IOException e) {
			// expected
		}

		FileUtils.delete(f);
	}

	@Test
	public void testDeleteEmptyTreeOk() throws IOException {
		File t = new File(trash, "t");
		FileUtils.mkdir(t);
		FileUtils.mkdir(new File(t, "d"));
		FileUtils.mkdir(new File(new File(t, "d"), "e"));
		FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.RECURSIVE);
		assertFalse(t.exists());
	}

	@Test
	public void testDeleteNotEmptyTreeNotOk() throws IOException {
		File t = new File(trash, "t");
		FileUtils.mkdir(t);
		FileUtils.mkdir(new File(t, "d"));
		File f = new File(new File(t, "d"), "f");
		FileUtils.createNewFile(f);
		FileUtils.mkdir(new File(new File(t, "d"), "e"));
		try {
			FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.RECURSIVE);
			fail("expected failure to delete f");
		} catch (IOException e) {
			assertTrue(e.getMessage().endsWith(f.getAbsolutePath()));
		}
		assertTrue(t.exists());
	}

	@Test
	public void testDeleteNotEmptyTreeNotOkButIgnoreFail() throws IOException {
		File t = new File(trash, "t");
		FileUtils.mkdir(t);
		FileUtils.mkdir(new File(t, "d"));
		File f = new File(new File(t, "d"), "f");
		FileUtils.createNewFile(f);
		File e = new File(new File(t, "d"), "e");
		FileUtils.mkdir(e);
		FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.RECURSIVE
				| FileUtils.IGNORE_ERRORS);
		// Should have deleted as much as possible, but not all
		assertTrue(t.exists());
		assertTrue(f.exists());
		assertFalse(e.exists());
	}

	@Test
	public void testRenameOverNonExistingFile() throws IOException {
		File d = new File(trash, "d");
		FileUtils.mkdirs(d);
		File f1 = new File(trash, "d/f");
		File f2 = new File(trash, "d/g");
		JGitTestUtil.write(f1, "f1");
		// test
		FileUtils.rename(f1, f2);
		assertFalse(f1.exists());
		assertTrue(f2.exists());
		assertEquals("f1", JGitTestUtil.read(f2));
	}

	@Test
	public void testRenameOverExistingFile() throws IOException {
		File d = new File(trash, "d");
		FileUtils.mkdirs(d);
		File f1 = new File(trash, "d/f");
		File f2 = new File(trash, "d/g");
		JGitTestUtil.write(f1, "f1");
		JGitTestUtil.write(f2, "f2");
		// test
		FileUtils.rename(f1, f2);
		assertFalse(f1.exists());
		assertTrue(f2.exists());
		assertEquals("f1", JGitTestUtil.read(f2));
	}

	@Test
	public void testRenameOverExistingNonEmptyDirectory() throws IOException {
		File d = new File(trash, "d");
		FileUtils.mkdirs(d);
		File f1 = new File(trash, "d/f");
		File f2 = new File(trash, "d/g");
		File d1 = new File(trash, "d/g/h/i");
		File f3 = new File(trash, "d/g/h/f");
		FileUtils.mkdirs(d1);
		JGitTestUtil.write(f1, "f1");
		JGitTestUtil.write(f3, "f3");
		// test
		try {
			FileUtils.rename(f1, f2);
			fail("rename to non-empty directory should fail");
		} catch (IOException e) {
			assertEquals("f1", JGitTestUtil.read(f1)); // untouched source
			assertEquals("f3", JGitTestUtil.read(f3)); // untouched
			// empty directories within f2 may or may not have been deleted
		}
	}

	@Test
	public void testRenameOverExistingEmptyDirectory() throws IOException {
		File d = new File(trash, "d");
		FileUtils.mkdirs(d);
		File f1 = new File(trash, "d/f");
		File f2 = new File(trash, "d/g");
		File d1 = new File(trash, "d/g/h/i");
		FileUtils.mkdirs(d1);
		JGitTestUtil.write(f1, "f1");
		// test
		FileUtils.rename(f1, f2);
		assertFalse(f1.exists());
		assertTrue(f2.exists());
		assertEquals("f1", JGitTestUtil.read(f2));
	}

	@Test
	public void testCreateSymlink() throws IOException {
		FS fs = FS.DETECTED;
		// show test as ignored if the FS doesn't support symlinks
		Assume.assumeTrue(fs.supportsSymlinks());
		fs.createSymLink(new File(trash, "x"), "y");
		String target = fs.readSymLink(new File(trash, "x"));
		assertEquals("y", target);
	}

	@Test
	public void testCreateSymlinkOverrideExisting() throws IOException {
		FS fs = FS.DETECTED;
		// show test as ignored if the FS doesn't support symlinks
		Assume.assumeTrue(fs.supportsSymlinks());
		File file = new File(trash, "x");
		fs.createSymLink(file, "y");
		String target = fs.readSymLink(file);
		assertEquals("y", target);
		fs.createSymLink(file, "z");
		target = fs.readSymLink(file);
		assertEquals("z", target);
	}

	@Test
	public void testRelativize_doc() {
		// This is the example from the javadoc
		String base = toOSPathString("c:\\Users\\jdoe\\eclipse\\git\\project");
		String other = toOSPathString("c:\\Users\\jdoe\\eclipse\\git\\another_project\\pom.xml");
		String expected = toOSPathString("..\\another_project\\pom.xml");

		String actual = FileUtils.relativizeNativePath(base, other);
		assertEquals(expected, actual);
	}

	@Test
	public void testRelativize_mixedCase() {
		SystemReader systemReader = SystemReader.getInstance();
		String base = toOSPathString("C:\\git\\jgit");
		String other = toOSPathString("C:\\Git\\test\\d\\f.txt");
		String expectedCaseInsensitive = toOSPathString("..\\test\\d\\f.txt");
		String expectedCaseSensitive = toOSPathString("..\\..\\Git\\test\\d\\f.txt");

		if (systemReader.isWindows()) {
			String actual = FileUtils.relativizeNativePath(base, other);
			assertEquals(expectedCaseInsensitive, actual);
		} else if (systemReader.isMacOS()) {
			String actual = FileUtils.relativizeNativePath(base, other);
			assertEquals(expectedCaseInsensitive, actual);
		} else {
			String actual = FileUtils.relativizeNativePath(base, other);
			assertEquals(expectedCaseSensitive, actual);
		}
	}

	@Test
	public void testRelativize_scheme() {
		String base = toOSPathString("file:/home/eclipse/runtime-New_configuration/project_1/file.java");
		String other = toOSPathString("file:/home/eclipse/runtime-New_configuration/project");
		// 'file.java' is treated as a folder
		String expected = toOSPathString("../../project");

		String actual = FileUtils.relativizeNativePath(base, other);
		assertEquals(expected, actual);
	}

	@Test
	public void testRelativize_equalPaths() {
		String base = toOSPathString("file:/home/eclipse/runtime-New_configuration/project_1");
		String other = toOSPathString("file:/home/eclipse/runtime-New_configuration/project_1");
		String expected = "";

		String actual = FileUtils.relativizeNativePath(base, other);
		assertEquals(expected, actual);
	}

	@Test
	public void testRelativize_whitespaces() {
		String base = toOSPathString("/home/eclipse 3.4/runtime New_configuration/project_1");
		String other = toOSPathString("/home/eclipse 3.4/runtime New_configuration/project_1/file");
		String expected = "file";

		String actual = FileUtils.relativizeNativePath(base, other);
		assertEquals(expected, actual);
	}

	@Test
	public void testDeleteSymlinkToDirectoryDoesNotDeleteTarget()
			throws IOException {
		org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
		FS fs = FS.DETECTED;
		File dir = new File(trash, "dir");
		File file = new File(dir, "file");
		File link = new File(trash, "link");
		FileUtils.mkdirs(dir);
		FileUtils.createNewFile(file);
		fs.createSymLink(link, "dir");
		FileUtils.delete(link, FileUtils.RECURSIVE);
		assertFalse(link.exists());
		assertTrue(dir.exists());
		assertTrue(file.exists());
	}

	@Test
	public void testAtomicMove() throws IOException {
		File src = new File(trash, "src");
		Files.createFile(src.toPath());
		File dst = new File(trash, "dst");
		FileUtils.rename(src, dst, StandardCopyOption.ATOMIC_MOVE);
		assertFalse(Files.exists(src.toPath()));
		assertTrue(Files.exists(dst.toPath()));
	}

	private String toOSPathString(String path) {
		return path.replaceAll("/|\\\\",
				Matcher.quoteReplacement(File.separator));
	}

	@Test
	public void testIsStaleFileHandleWithDirectCause() throws Exception {
		assertTrue(FileUtils.isStaleFileHandle(IO_EXCEPTION));
	}

	@Test
	public void testIsStaleFileHandleWithIndirectCause() throws Exception {
		assertFalse(
				FileUtils.isStaleFileHandle(IO_EXCEPTION_WITH_CAUSE));
	}

	@Test
	public void testIsStaleFileHandleInCausalChainWithDirectCause()
			throws Exception {
		assertTrue(
				FileUtils.isStaleFileHandleInCausalChain(IO_EXCEPTION));
	}

	@Test
	public void testIsStaleFileHandleInCausalChainWithIndirectCause()
			throws Exception {
		assertTrue(FileUtils
				.isStaleFileHandleInCausalChain(IO_EXCEPTION_WITH_CAUSE));
	}
}
