/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.io.file;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFileAttributes;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.test.TestUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.Test;

/**
 * Tests {@link PathUtils}.
 */
public class PathUtilsTest extends AbstractTempDirTest {

    private static final String STRING_FIXTURE = "Hello World";

    private static final byte[] BYTE_ARRAY_FIXTURE = STRING_FIXTURE.getBytes(StandardCharsets.UTF_8);

    private static final String TEST_JAR_NAME = "test.jar";

    private static final String TEST_JAR_PATH = "src/test/resources/org/apache/commons/io/test.jar";

    private static final String PATH_FIXTURE = "NOTICE.txt";

    private Path current() {
        return PathUtils.current();
    }

    private Long getLastModifiedMillis(final Path file) throws IOException {
        return Files.getLastModifiedTime(file).toMillis();
    }

    private Path getNonExistentPath() {
        return Paths.get("/does not exist/for/certain");
    }

    private FileSystem openArchive(final Path p, final boolean createNew) throws IOException {
        if (createNew) {
            final Map<String, String> env = new HashMap<>();
            env.put("create", "true");
            final URI fileUri = p.toAbsolutePath().toUri();
            final URI uri = URI.create("jar:" + fileUri.toASCIIString());
            return FileSystems.newFileSystem(uri, env, null);
        }
        return FileSystems.newFileSystem(p, (ClassLoader) null);
    }

    private void setLastModifiedMillis(final Path file, final long millis) throws IOException {
        Files.setLastModifiedTime(file, FileTime.fromMillis(millis));
    }

    @Test
    public void testCopyDirectoryForDifferentFilesystemsWithAbsolutePath() throws IOException {
        final Path archivePath = Paths.get(TEST_JAR_PATH);
        try (FileSystem archive = openArchive(archivePath, false)) {
            // relative jar -> absolute dir
            Path sourceDir = archive.getPath("dir1");
            PathUtils.copyDirectory(sourceDir, tempDirPath);
            assertTrue(Files.exists(tempDirPath.resolve("f1")));

            // absolute jar -> absolute dir
            sourceDir = archive.getPath("/next");
            PathUtils.copyDirectory(sourceDir, tempDirPath);
            assertTrue(Files.exists(tempDirPath.resolve("dir")));
        }
    }

    @Test
    public void testCopyDirectoryForDifferentFilesystemsWithAbsolutePathReverse() throws IOException {
        try (FileSystem archive = openArchive(tempDirPath.resolve(TEST_JAR_NAME), true)) {
            // absolute dir -> relative jar
            Path targetDir = archive.getPath("target");
            Files.createDirectory(targetDir);
            final Path sourceDir = Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2").toAbsolutePath();
            PathUtils.copyDirectory(sourceDir, targetDir);
            assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));

            // absolute dir -> absolute jar
            targetDir = archive.getPath("/");
            PathUtils.copyDirectory(sourceDir, targetDir);
            assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));
        }
    }

    @Test
    public void testCopyDirectoryForDifferentFilesystemsWithRelativePath() throws IOException {
        final Path archivePath = Paths.get(TEST_JAR_PATH);
        try (FileSystem archive = openArchive(archivePath, false);
                final FileSystem targetArchive = openArchive(tempDirPath.resolve(TEST_JAR_NAME), true)) {
            final Path targetDir = targetArchive.getPath("targetDir");
            Files.createDirectory(targetDir);
            // relative jar -> relative dir
            Path sourceDir = archive.getPath("next");
            PathUtils.copyDirectory(sourceDir, targetDir);
            assertTrue(Files.exists(targetDir.resolve("dir")));

            // absolute jar -> relative dir
            sourceDir = archive.getPath("/dir1");
            PathUtils.copyDirectory(sourceDir, targetDir);
            assertTrue(Files.exists(targetDir.resolve("f1")));
        }
    }

    @Test
    public void testCopyDirectoryForDifferentFilesystemsWithRelativePathReverse() throws IOException {
        try (FileSystem archive = openArchive(tempDirPath.resolve(TEST_JAR_NAME), true)) {
            // relative dir -> relative jar
            Path targetDir = archive.getPath("target");
            Files.createDirectory(targetDir);
            final Path sourceDir = Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2");
            PathUtils.copyDirectory(sourceDir, targetDir);
            assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));

            // relative dir -> absolute jar
            targetDir = archive.getPath("/");
            PathUtils.copyDirectory(sourceDir, targetDir);
            assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));
        }
    }

    @Test
    public void testCopyFile() throws IOException {
        final Path sourceFile = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/file-size-1.bin");
        final Path targetFile = PathUtils.copyFileToDirectory(sourceFile, tempDirPath);
        assertTrue(Files.exists(targetFile));
        assertEquals(Files.size(sourceFile), Files.size(targetFile));
    }

    @Test
    public void testCopyURL() throws IOException {
        final Path sourceFile = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/file-size-1.bin");
        final URL url = new URL("file:///" + FilenameUtils.getPath(sourceFile.toAbsolutePath().toString()) + sourceFile.getFileName());
        final Path targetFile = PathUtils.copyFileToDirectory(url, tempDirPath);
        assertTrue(Files.exists(targetFile));
        assertEquals(Files.size(sourceFile), Files.size(targetFile));
    }

    @Test
    public void testCreateDirectoriesAlreadyExists() throws IOException {
        assertEquals(tempDirPath.getParent(), PathUtils.createParentDirectories(tempDirPath));
    }

    @SuppressWarnings("resource") // FileSystems.getDefault() is a singleton
    @Test
    public void testCreateDirectoriesForRoots() throws IOException {
        for (final Path path : FileSystems.getDefault().getRootDirectories()) {
            final Path parent = path.getParent();
            assertNull(parent);
            assertEquals(parent, PathUtils.createParentDirectories(path));
        }
    }

    @Test
    public void testCreateDirectoriesForRootsLinkOptionNull() throws IOException {
        for (final File f : File.listRoots()) {
            final Path path = f.toPath();
            assertEquals(path.getParent(), PathUtils.createParentDirectories(path, (LinkOption) null));
        }
    }

    @Test
    public void testCreateDirectoriesNew() throws IOException {
        assertEquals(tempDirPath, PathUtils.createParentDirectories(tempDirPath.resolve("child")));
    }

    @Test
    public void testCreateDirectoriesSymlink() throws IOException {
        final Path symlinkedDir = createTempSymlinkedRelativeDir(tempDirPath);
        final String leafDirName = "child";
        final Path newDirFollowed = PathUtils.createParentDirectories(symlinkedDir.resolve(leafDirName), PathUtils.NULL_LINK_OPTION);
        assertEquals(Files.readSymbolicLink(symlinkedDir), newDirFollowed);
    }

    @Test
    public void testCreateDirectoriesSymlinkClashing() throws IOException {
        final Path symlinkedDir = createTempSymlinkedRelativeDir(tempDirPath);
        assertEquals(symlinkedDir, PathUtils.createParentDirectories(symlinkedDir.resolve("child")));
    }

    @Test
    public void testGetBaseNamePathBaseCases() {
        assertEquals("bar", PathUtils.getBaseName(Paths.get("a/b/c/bar.foo")));
        assertEquals("foo", PathUtils.getBaseName(Paths.get("foo")));
        assertEquals("", PathUtils.getBaseName(Paths.get("")));
        assertEquals("", PathUtils.getBaseName(Paths.get(".")));
        for (final File f : File.listRoots()) {
            assertNull(PathUtils.getBaseName(f.toPath()));
        }
        if (SystemUtils.IS_OS_WINDOWS) {
            assertNull(PathUtils.getBaseName(Paths.get("C:\\")));
        }
    }

    @Test
    public void testGetBaseNamePathCornerCases() {
        assertNull(PathUtils.getBaseName((Path) null));
        assertEquals("foo", PathUtils.getBaseName(Paths.get("foo.")));
        assertEquals("", PathUtils.getBaseName(Paths.get("bar/.foo")));
    }

    @Test
    public void testGetExtension() {
        assertNull(PathUtils.getExtension(null));
        assertEquals("ext", PathUtils.getExtension(Paths.get("file.ext")));
        assertEquals("", PathUtils.getExtension(Paths.get("README")));
        assertEquals("com", PathUtils.getExtension(Paths.get("domain.dot.com")));
        assertEquals("jpeg", PathUtils.getExtension(Paths.get("image.jpeg")));
        assertEquals("", PathUtils.getExtension(Paths.get("a.b/c")));
        assertEquals("txt", PathUtils.getExtension(Paths.get("a.b/c.txt")));
        assertEquals("", PathUtils.getExtension(Paths.get("a/b/c")));
        assertEquals("", PathUtils.getExtension(Paths.get("a.b\\c")));
        assertEquals("txt", PathUtils.getExtension(Paths.get("a.b\\c.txt")));
        assertEquals("", PathUtils.getExtension(Paths.get("a\\b\\c")));
        assertEquals("", PathUtils.getExtension(Paths.get("C:\\temp\\foo.bar\\README")));
        assertEquals("ext", PathUtils.getExtension(Paths.get("../filename.ext")));

        if (File.separatorChar != '\\') {
            // Upwards compatibility:
            assertEquals("txt", PathUtils.getExtension(Paths.get("foo.exe:bar.txt")));
        }
    }

    @Test
    public void testGetFileName() {
        assertNull(PathUtils.getFileName(null, null));
        assertNull(PathUtils.getFileName(null, Path::toString));
        assertNull(PathUtils.getFileName(Paths.get("/"), Path::toString));
        assertNull(PathUtils.getFileName(Paths.get("/"), Path::toString));
        assertEquals("", PathUtils.getFileName(Paths.get(""), Path::toString));
        assertEquals("a", PathUtils.getFileName(Paths.get("a"), Path::toString));
        assertEquals("a", PathUtils.getFileName(Paths.get("p", "a"), Path::toString));
    }

    @Test
    public void testGetFileNameString() {
        assertNull(PathUtils.getFileNameString(Paths.get("/")));
        assertEquals("", PathUtils.getFileNameString(Paths.get("")));
        assertEquals("a", PathUtils.getFileNameString(Paths.get("a")));
        assertEquals("a", PathUtils.getFileNameString(Paths.get("p", "a")));
    }

    @Test
    public void testGetLastModifiedFileTime_File_Present() throws IOException {
        assertNotNull(PathUtils.getLastModifiedFileTime(current().toFile()));
    }

    @Test
    public void testGetLastModifiedFileTime_Path_Absent() throws IOException {
        assertNull(PathUtils.getLastModifiedFileTime(getNonExistentPath()));
    }

    @Test
    public void testGetLastModifiedFileTime_Path_FileTime_Absent() throws IOException {
        final FileTime fromMillis = FileTime.fromMillis(0);
        assertEquals(fromMillis, PathUtils.getLastModifiedFileTime(getNonExistentPath(), fromMillis));
    }

    @Test
    public void testGetLastModifiedFileTime_Path_Present() throws IOException {
        assertNotNull(PathUtils.getLastModifiedFileTime(current()));
    }

    @Test
    public void testGetLastModifiedFileTime_URI_Present() throws IOException {
        assertNotNull(PathUtils.getLastModifiedFileTime(current().toUri()));
    }

    @Test
    public void testGetLastModifiedFileTime_URL_Present() throws IOException, URISyntaxException {
        assertNotNull(PathUtils.getLastModifiedFileTime(current().toUri().toURL()));
    }

    @Test
    public void testGetTempDirectory() {
        final Path tempDirectory = Paths.get(System.getProperty("java.io.tmpdir"));
        assertEquals(tempDirectory, PathUtils.getTempDirectory());
    }

    @Test
    public void testIsDirectory() throws IOException {
        assertFalse(PathUtils.isDirectory(null));

        assertTrue(PathUtils.isDirectory(tempDirPath));
        try (TempFile testFile1 = TempFile.create(tempDirPath, "prefix", null)) {
            assertFalse(PathUtils.isDirectory(testFile1.get()));

            Path ref = null;
            try (TempDirectory tempDir = TempDirectory.create(getClass().getCanonicalName())) {
                ref = tempDir.get();
                assertTrue(PathUtils.isDirectory(tempDir.get()));
            }
            assertFalse(PathUtils.isDirectory(ref));
        }
    }

    @Test
    public void testIsPosix() throws IOException {
        boolean isPosix;
        try {
            Files.getPosixFilePermissions(current());
            isPosix = true;
        } catch (final UnsupportedOperationException e) {
            isPosix = false;
        }
        assertEquals(isPosix, PathUtils.isPosix(current()));
    }

    @Test
    public void testIsRegularFile() throws IOException {
        assertFalse(PathUtils.isRegularFile(null));

        assertFalse(PathUtils.isRegularFile(tempDirPath));
        try (TempFile testFile1 = TempFile.create(tempDirPath, "prefix", null)) {
            assertTrue(PathUtils.isRegularFile(testFile1.get()));

            Files.delete(testFile1.get());
            assertFalse(PathUtils.isRegularFile(testFile1.get()));
        }
    }

    @Test
    public void testNewDirectoryStream() throws Exception {
        final PathFilter pathFilter = new NameFileFilter(PATH_FIXTURE);
        try (DirectoryStream<Path> stream = PathUtils.newDirectoryStream(current(), pathFilter)) {
            final Iterator<Path> iterator = stream.iterator();
            final Path path = iterator.next();
            assertEquals(PATH_FIXTURE, PathUtils.getFileNameString(path));
            assertFalse(iterator.hasNext());
        }
    }

    @Test
    public void testNewOutputStreamExistingFileAppendFalse() throws IOException {
        testNewOutputStreamNewFile(false);
        testNewOutputStreamNewFile(false);
    }

    @Test
    public void testNewOutputStreamExistingFileAppendTrue() throws IOException {
        testNewOutputStreamNewFile(true);
        final Path file = writeToNewOutputStream(true);
        assertArrayEquals(ArrayUtils.addAll(BYTE_ARRAY_FIXTURE, BYTE_ARRAY_FIXTURE), Files.readAllBytes(file));
    }

    public void testNewOutputStreamNewFile(final boolean append) throws IOException {
        final Path file = writeToNewOutputStream(append);
        assertArrayEquals(BYTE_ARRAY_FIXTURE, Files.readAllBytes(file));
    }

    @Test
    public void testNewOutputStreamNewFileAppendFalse() throws IOException {
        testNewOutputStreamNewFile(false);
    }

    @Test
    public void testNewOutputStreamNewFileAppendTrue() throws IOException {
        testNewOutputStreamNewFile(true);
    }

    @Test
    public void testNewOutputStreamNewFileInsideExistingSymlinkedDir() throws IOException {
        final Path symlinkDir = createTempSymlinkedRelativeDir(tempDirPath);
        final Path file = symlinkDir.resolve("test.txt");
        try (OutputStream outputStream = PathUtils.newOutputStream(file, new LinkOption[] {})) {
            // empty
        }
        try (OutputStream outputStream = PathUtils.newOutputStream(file, null)) {
            // empty
        }
        try (OutputStream outputStream = PathUtils.newOutputStream(file, true)) {
            // empty
        }
        try (OutputStream outputStream = PathUtils.newOutputStream(file, false)) {
            // empty
        }
    }

    @Test
    public void testReadAttributesPosix() throws IOException {
        boolean isPosix;
        try {
            Files.getPosixFilePermissions(current());
            isPosix = true;
        } catch (final UnsupportedOperationException e) {
            isPosix = false;
        }
        assertEquals(isPosix, PathUtils.readAttributes(current(), PosixFileAttributes.class) != null);
    }

    @Test
    public void testReadStringEmptyFile() throws IOException {
        final Path path = Paths.get("src/test/resources/org/apache/commons/io/test-file-empty.bin");
        assertEquals(StringUtils.EMPTY, PathUtils.readString(path, StandardCharsets.UTF_8));
        assertEquals(StringUtils.EMPTY, PathUtils.readString(path, null));
    }

    @Test
    public void testReadStringSimpleUtf8() throws IOException {
        final Path path = Paths.get("src/test/resources/org/apache/commons/io/test-file-simple-utf8.bin");
        final String expected = "ABC\r\n";
        assertEquals(expected, PathUtils.readString(path, StandardCharsets.UTF_8));
        assertEquals(expected, PathUtils.readString(path, null));
    }

    @Test
    public void testSetReadOnlyFile() throws IOException {
        final Path resolved = tempDirPath.resolve("testSetReadOnlyFile.txt");
        // Ask now, as we are allowed before editing parent permissions.
        final boolean isPosix = PathUtils.isPosix(tempDirPath);

        // TEMP HACK
        assumeFalse(SystemUtils.IS_OS_LINUX);

        PathUtils.writeString(resolved, "test", StandardCharsets.UTF_8);
        final boolean readable = Files.isReadable(resolved);
        final boolean writable = Files.isWritable(resolved);
        final boolean regularFile = Files.isRegularFile(resolved);
        final boolean executable = Files.isExecutable(resolved);
        final boolean hidden = Files.isHidden(resolved);
        final boolean directory = Files.isDirectory(resolved);
        final boolean symbolicLink = Files.isSymbolicLink(resolved);
        // Sanity checks
        assertTrue(readable);
        assertTrue(writable);
        // Test A
        PathUtils.setReadOnly(resolved, false);
        assertTrue(Files.isReadable(resolved), "isReadable");
        assertTrue(Files.isWritable(resolved), "isWritable");
        // Again, shouldn't blow up.
        PathUtils.setReadOnly(resolved, false);
        assertTrue(Files.isReadable(resolved), "isReadable");
        assertTrue(Files.isWritable(resolved), "isWritable");
        //
        assertEquals(regularFile, Files.isReadable(resolved));
        assertEquals(executable, Files.isExecutable(resolved));
        assertEquals(hidden, Files.isHidden(resolved));
        assertEquals(directory, Files.isDirectory(resolved));
        assertEquals(symbolicLink, Files.isSymbolicLink(resolved));
        // Test B
        PathUtils.setReadOnly(resolved, true);
        if (isPosix) {
            // On POSIX, now that the parent is not WX, the file is not readable.
            assertFalse(Files.isReadable(resolved), "isReadable");
        } else {
            assertTrue(Files.isReadable(resolved), "isReadable");
        }
        assertFalse(Files.isWritable(resolved), "isWritable");
        final DosFileAttributeView dosFileAttributeView = PathUtils.getDosFileAttributeView(resolved);
        if (dosFileAttributeView != null) {
            assertTrue(dosFileAttributeView.readAttributes().isReadOnly());
        }
        if (isPosix) {
            assertFalse(Files.isReadable(resolved));
        } else {
            assertEquals(regularFile, Files.isReadable(resolved));
        }
        assertEquals(executable, Files.isExecutable(resolved));
        assertEquals(hidden, Files.isHidden(resolved));
        assertEquals(directory, Files.isDirectory(resolved));
        assertEquals(symbolicLink, Files.isSymbolicLink(resolved));
        //
        PathUtils.setReadOnly(resolved, false);
        PathUtils.deleteFile(resolved);
    }

    @Test
    public void testTouch() throws IOException {
        assertThrows(NullPointerException.class, () -> FileUtils.touch(null));

        final Path file = managedTempDirPath.resolve("touch.txt");
        Files.deleteIfExists(file);
        assertFalse(Files.exists(file), "Bad test: test file still exists");
        PathUtils.touch(file);
        assertTrue(Files.exists(file), "touch() created file");
        try (OutputStream out = Files.newOutputStream(file)) {
            assertEquals(0, Files.size(file), "Created empty file.");
            out.write(0);
        }
        assertEquals(1, Files.size(file), "Wrote one byte to file");
        final long y2k = new GregorianCalendar(2000, 0, 1).getTime().getTime();
        setLastModifiedMillis(file, y2k); // 0L fails on Win98
        assertEquals(y2k, getLastModifiedMillis(file), "Bad test: set lastModified set incorrect value");
        final long nowMillis = System.currentTimeMillis();
        PathUtils.touch(file);
        assertEquals(1, Files.size(file), "FileUtils.touch() didn't empty the file.");
        assertNotEquals(y2k, getLastModifiedMillis(file), "FileUtils.touch() changed lastModified");
        final int delta = 3000;
        assertTrue(getLastModifiedMillis(file) >= nowMillis - delta, "FileUtils.touch() changed lastModified to more than now-3s");
        assertTrue(getLastModifiedMillis(file) <= nowMillis + delta, "FileUtils.touch() changed lastModified to less than now+3s");
    }

    @Test
    public void testWriteStringToFile1() throws Exception {
        final Path file = tempDirPath.resolve("write.txt");
        PathUtils.writeString(file, "Hello /u1234", StandardCharsets.UTF_8);
        final byte[] text = "Hello /u1234".getBytes(StandardCharsets.UTF_8);
        TestUtils.assertEqualContent(text, file);
    }

    /**
     * Tests newOutputStream() here and don't use Files.write obviously.
     */
    private Path writeToNewOutputStream(final boolean append) throws IOException {
        final Path file = tempDirPath.resolve("test1.txt");
        try (OutputStream os = PathUtils.newOutputStream(file, append)) {
            os.write(BYTE_ARRAY_FIXTURE);
        }
        return file;
    }

}
