// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.build.lib.vfs;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.appendWithoutExtension;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.commonAncestor;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.copyFile;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.copyTool;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.moveFile;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.relativePath;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.removeExtension;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.touchFile;
import static com.google.devtools.build.lib.vfs.FileSystemUtils.traverseTree;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.Lists;
import com.google.devtools.build.lib.testutil.BlazeTestUtils;
import com.google.devtools.build.lib.testutil.ManualClock;
import com.google.devtools.build.lib.vfs.FileSystemUtils.MoveResult;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * This class tests the file system utilities.
 */
@RunWith(JUnit4.class)
public class FileSystemUtilsTest {
  private ManualClock clock;
  private FileSystem fileSystem;
  private Path workingDir;

  @Before
  public final void initializeFileSystem() throws Exception  {
    clock = new ManualClock();
    fileSystem = new InMemoryFileSystem(clock);
    workingDir = fileSystem.getPath("/workingDir");
    workingDir.createDirectory();
  }

  Path topDir;
  Path file1;
  Path file2;
  Path aDir;
  Path bDir;
  Path file3;
  Path innerDir;
  Path link1;
  Path dirLink;
  Path file4;
  Path file5;

  /*
   * Build a directory tree that looks like:
   *   top-dir/
   *     file-1
   *     file-2
   *     a-dir/
   *       file-3
   *       inner-dir/
   *         link-1 => file-4
   *         dir-link => b-dir
   *   file-4
   */
  private void createTestDirectoryTree() throws IOException {
    topDir = fileSystem.getPath("/top-dir");
    file1 = fileSystem.getPath("/top-dir/file-1");
    file2 = fileSystem.getPath("/top-dir/file-2");
    aDir = fileSystem.getPath("/top-dir/a-dir");
    bDir = fileSystem.getPath("/top-dir/b-dir");
    file3 = fileSystem.getPath("/top-dir/a-dir/file-3");
    innerDir = fileSystem.getPath("/top-dir/a-dir/inner-dir");
    link1 = fileSystem.getPath("/top-dir/a-dir/inner-dir/link-1");
    dirLink = fileSystem.getPath("/top-dir/a-dir/inner-dir/dir-link");
    file4 = fileSystem.getPath("/file-4");
    file5 = fileSystem.getPath("/top-dir/b-dir/file-5");

    topDir.createDirectory();
    FileSystemUtils.createEmptyFile(file1);
    FileSystemUtils.createEmptyFile(file2);
    aDir.createDirectory();
    bDir.createDirectory();
    FileSystemUtils.createEmptyFile(file3);
    innerDir.createDirectory();
    link1.createSymbolicLink(file4);  // simple symlink
    dirLink.createSymbolicLink(bDir);
    FileSystemUtils.createEmptyFile(file4);
    FileSystemUtils.createEmptyFile(file5);
  }

  private Path checkTestDirectoryTreesBelowExceptSymlinks(Path toPath) throws IOException {
    Path copiedFile1 = toPath.getChild("file-1");
    assertThat(copiedFile1.exists()).isTrue();
    assertThat(copiedFile1.isFile()).isTrue();

    Path copiedFile2 = toPath.getChild("file-2");
    assertThat(copiedFile2.exists()).isTrue();
    assertThat(copiedFile2.isFile()).isTrue();

    Path copiedADir = toPath.getChild("a-dir");
    assertThat(copiedADir.exists()).isTrue();
    assertThat(copiedADir.isDirectory()).isTrue();
    Collection<Path> aDirEntries = copiedADir.getDirectoryEntries();
    assertThat(aDirEntries).hasSize(2);

    Path copiedFile3 = copiedADir.getChild("file-3");
    assertThat(copiedFile3.exists()).isTrue();
    assertThat(copiedFile3.isFile()).isTrue();

    Path copiedInnerDir = copiedADir.getChild("inner-dir");
    assertThat(copiedInnerDir.exists()).isTrue();
    assertThat(copiedInnerDir.isDirectory()).isTrue();
    return copiedInnerDir;
  }

  private void checkTestDirectoryTreesBelow(Path toPath) throws IOException {
    Path copiedInnerDir = checkTestDirectoryTreesBelowExceptSymlinks(toPath);
    Path copiedLink1 = copiedInnerDir.getChild("link-1");
    assertThat(copiedLink1.exists()).isTrue();
    assertThat(copiedLink1.isSymbolicLink()).isFalse();

    Path copiedDirLink = copiedInnerDir.getChild("dir-link");
    assertThat(copiedDirLink.exists()).isTrue();
    assertThat(copiedDirLink.isDirectory()).isTrue();
    assertThat(copiedDirLink.getChild("file-5").exists()).isTrue();
  }

  // tests

  @Test
  public void testChangeModtime() throws IOException {
    Path file = fileSystem.getPath("/my-file");
    assertThrows(FileNotFoundException.class, () -> BlazeTestUtils.changeModtime(file));
    FileSystemUtils.createEmptyFile(file);
    long prevMtime = file.getLastModifiedTime();
    BlazeTestUtils.changeModtime(file);
    assertThat(prevMtime == file.getLastModifiedTime()).isFalse();
  }

  @Test
  public void testCommonAncestor() {
    assertThat(commonAncestor(topDir, topDir)).isEqualTo(topDir);
    assertThat(commonAncestor(file1, file3)).isEqualTo(topDir);
    assertThat(commonAncestor(file1, dirLink)).isEqualTo(topDir);
  }

  @Test
  public void testRelativePath() throws IOException {
    createTestDirectoryTree();
    assertThat(
            relativePath(PathFragment.create("/top-dir"), PathFragment.create("/top-dir/file-1"))
                .getPathString())
        .isEqualTo("file-1");
    assertThat(
            relativePath(PathFragment.create("/top-dir"), PathFragment.create("/top-dir"))
                .getPathString())
        .isEqualTo("");
    assertThat(
            relativePath(
                    PathFragment.create("/top-dir"),
                    PathFragment.create("/top-dir/a-dir/inner-dir/dir-link"))
                .getPathString())
        .isEqualTo("a-dir/inner-dir/dir-link");
    assertThat(
            relativePath(PathFragment.create("/top-dir"), PathFragment.create("/file-4"))
                .getPathString())
        .isEqualTo("../file-4");
    assertThat(
            relativePath(
                    PathFragment.create("/top-dir/a-dir/inner-dir"), PathFragment.create("/file-4"))
                .getPathString())
        .isEqualTo("../../../file-4");
  }

  @Test
  public void testRemoveExtension_Strings() throws Exception {
    assertThat(removeExtension("foo.c")).isEqualTo("foo");
    assertThat(removeExtension("a/foo.c")).isEqualTo("a/foo");
    assertThat(removeExtension("a.b/foo")).isEqualTo("a.b/foo");
    assertThat(removeExtension("foo")).isEqualTo("foo");
    assertThat(removeExtension("foo.")).isEqualTo("foo");
  }

  @Test
  public void testRemoveExtension_Paths() throws Exception {
    assertPath("/foo", removeExtension(fileSystem.getPath("/foo.c")));
    assertPath("/a/foo", removeExtension(fileSystem.getPath("/a/foo.c")));
    assertPath("/a.b/foo", removeExtension(fileSystem.getPath("/a.b/foo")));
    assertPath("/foo", removeExtension(fileSystem.getPath("/foo")));
    assertPath("/foo", removeExtension(fileSystem.getPath("/foo.")));
  }

  private static void assertPath(String expected, PathFragment actual) {
    assertThat(actual.getPathString()).isEqualTo(expected);
  }

  private static void assertPath(String expected, Path actual) {
    assertThat(actual.getPathString()).isEqualTo(expected);
  }

  @Test
  public void testReplaceExtension_Path() throws Exception {
    assertPath("/foo/bar.baz",
               FileSystemUtils.replaceExtension(fileSystem.getPath("/foo/bar"), ".baz"));
    assertPath("/foo/bar.baz",
               FileSystemUtils.replaceExtension(fileSystem.getPath("/foo/bar.cc"), ".baz"));
    assertPath("/foo.baz", FileSystemUtils.replaceExtension(fileSystem.getPath("/foo/"), ".baz"));
    assertPath("/foo.baz",
               FileSystemUtils.replaceExtension(fileSystem.getPath("/foo.cc/"), ".baz"));
    assertPath("/foo.baz", FileSystemUtils.replaceExtension(fileSystem.getPath("/foo"), ".baz"));
    assertPath("/foo.baz", FileSystemUtils.replaceExtension(fileSystem.getPath("/foo.cc"), ".baz"));
    assertPath("/.baz", FileSystemUtils.replaceExtension(fileSystem.getPath("/.cc"), ".baz"));
    assertThat(FileSystemUtils.replaceExtension(fileSystem.getPath("/"), ".baz")).isNull();
  }

  @Test
  public void testReplaceExtension_PathFragment() throws Exception {
    assertPath("foo/bar.baz",
               FileSystemUtils.replaceExtension(PathFragment.create("foo/bar"), ".baz"));
    assertPath("foo/bar.baz",
               FileSystemUtils.replaceExtension(PathFragment.create("foo/bar.cc"), ".baz"));
    assertPath("/foo/bar.baz",
               FileSystemUtils.replaceExtension(PathFragment.create("/foo/bar"), ".baz"));
    assertPath("/foo/bar.baz",
               FileSystemUtils.replaceExtension(PathFragment.create("/foo/bar.cc"), ".baz"));
    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo/"), ".baz"));
    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo.cc/"), ".baz"));
    assertPath("/foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("/foo/"), ".baz"));
    assertPath("/foo.baz",
               FileSystemUtils.replaceExtension(PathFragment.create("/foo.cc/"), ".baz"));
    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo"), ".baz"));
    assertPath("foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("foo.cc"), ".baz"));
    assertPath("/foo.baz", FileSystemUtils.replaceExtension(PathFragment.create("/foo"), ".baz"));
    assertPath("/foo.baz",
               FileSystemUtils.replaceExtension(PathFragment.create("/foo.cc"), ".baz"));
    assertPath(".baz", FileSystemUtils.replaceExtension(PathFragment.create(".cc"), ".baz"));
    assertThat(FileSystemUtils.replaceExtension(PathFragment.create("/"), ".baz")).isNull();
    assertThat(FileSystemUtils.replaceExtension(PathFragment.create(""), ".baz")).isNull();
    assertPath("foo/bar.baz",
        FileSystemUtils.replaceExtension(PathFragment.create("foo/bar.pony"), ".baz", ".pony"));
    assertPath("foo/bar.baz",
        FileSystemUtils.replaceExtension(PathFragment.create("foo/bar"), ".baz", ""));
    assertThat(FileSystemUtils.replaceExtension(PathFragment.create(""), ".baz", ".pony")).isNull();
    assertThat(
            FileSystemUtils.replaceExtension(
                PathFragment.create("foo/bar.pony"), ".baz", ".unicorn"))
        .isNull();
  }

  @Test
  public void testAppendWithoutExtension() throws Exception {
    assertPath("libfoo-src.jar",
        appendWithoutExtension(PathFragment.create("libfoo.jar"), "-src"));
    assertPath("foo/libfoo-src.jar",
        appendWithoutExtension(PathFragment.create("foo/libfoo.jar"), "-src"));
    assertPath("java/com/google/foo/libfoo-src.jar",
        appendWithoutExtension(PathFragment.create("java/com/google/foo/libfoo.jar"), "-src"));
    assertPath("libfoo.bar-src.jar",
        appendWithoutExtension(PathFragment.create("libfoo.bar.jar"), "-src"));
    assertPath("libfoo-src",
        appendWithoutExtension(PathFragment.create("libfoo"), "-src"));
    assertPath("libfoo-src.jar",
        appendWithoutExtension(PathFragment.create("libfoo.jar/"), "-src"));
    assertPath("libfoo.src.jar",
        appendWithoutExtension(PathFragment.create("libfoo.jar"), ".src"));
    assertThat(appendWithoutExtension(PathFragment.create("/"), "-src")).isNull();
    assertThat(appendWithoutExtension(PathFragment.create(""), "-src")).isNull();
  }

  @Test
  public void testGetWorkingDirectory() {
    String userDir = System.getProperty("user.dir");

    assertThat(fileSystem.getPath(System.getProperty("user.dir", "/")))
        .isEqualTo(FileSystemUtils.getWorkingDirectory(fileSystem));

    System.setProperty("user.dir", "/blah/blah/blah");
    assertThat(fileSystem.getPath("/blah/blah/blah"))
        .isEqualTo(FileSystemUtils.getWorkingDirectory(fileSystem));

    System.setProperty("user.dir", userDir);
  }

  @Test
  public void testResolveRelativeToFilesystemWorkingDir() {
    PathFragment relativePath = PathFragment.create("relative/path");
    assertThat(workingDir.getRelative(relativePath))
        .isEqualTo(workingDir.getRelative(relativePath));

    PathFragment absolutePath = PathFragment.create("/absolute/path");
    assertThat(workingDir.getRelative(absolutePath)).isEqualTo(fileSystem.getPath(absolutePath));
  }

  @Test
  public void testTouchFileCreatesFile() throws IOException {
    createTestDirectoryTree();
    Path nonExistingFile = fileSystem.getPath("/previously-non-existing");
    assertThat(nonExistingFile.exists()).isFalse();
    touchFile(nonExistingFile);

    assertThat(nonExistingFile.exists()).isTrue();
  }

  @Test
  public void testTouchFileAdjustsFileTime() throws IOException {
    createTestDirectoryTree();
    Path testFile = file4;
    long oldTime = testFile.getLastModifiedTime();
    testFile.setLastModifiedTime(42);
    touchFile(testFile);

    assertThat(testFile.getLastModifiedTime()).isAtLeast(oldTime);
  }

  @Test
  public void testCopyFile() throws IOException {
    createTestDirectoryTree();
    Path originalFile = file1;
    byte[] content = new byte[] { 'a', 'b', 'c', 23, 42 };
    FileSystemUtils.writeContent(originalFile, content);

    Path copyTarget = file2;

    copyFile(originalFile, copyTarget);

    assertThat(FileSystemUtils.readContent(copyTarget)).isEqualTo(content);
  }

  @Test
  public void testMoveFile() throws IOException {
    createTestDirectoryTree();
    Path originalFile = file1;
    byte[] content = new byte[] { 'a', 'b', 'c', 23, 42 };
    FileSystemUtils.writeContent(originalFile, content);

    Path moveTarget = file2;

    assertThat(moveFile(originalFile, moveTarget)).isEqualTo(MoveResult.FILE_MOVED);

    assertThat(FileSystemUtils.readContent(moveTarget)).isEqualTo(content);
    assertThat(originalFile.exists()).isFalse();
  }

  @Test
  public void testMoveFileAcrossDevices() throws Exception {
    class MultipleDeviceFS extends InMemoryFileSystem {
      @Override
      public void renameTo(Path source, Path target) throws IOException {
        if (!source.startsWith(target.asFragment().subFragment(0, 1))) {
          throw new IOException("EXDEV");
        }
        super.renameTo(source, target);
      }
    }
    FileSystem fs = new MultipleDeviceFS();
    Path dev1 = fs.getPath("/fs1");
    dev1.createDirectory();
    Path dev2 = fs.getPath("/fs2");
    dev2.createDirectory();
    Path source = dev1.getChild("source");
    Path target = dev2.getChild("target");

    FileSystemUtils.writeContent(source, UTF_8, "hello, world");
    source.setLastModifiedTime(142);
    assertThat(FileSystemUtils.moveFile(source, target)).isEqualTo(MoveResult.FILE_COPIED);
    assertThat(source.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(target.isFile(Symlinks.NOFOLLOW)).isTrue();
    assertThat(FileSystemUtils.readContent(target, UTF_8)).isEqualTo("hello, world");
    assertThat(target.getLastModifiedTime()).isEqualTo(142);

    source.createSymbolicLink(PathFragment.create("link-target"));
    assertThat(FileSystemUtils.moveFile(source, target)).isEqualTo(MoveResult.FILE_COPIED);
    assertThat(source.exists(Symlinks.NOFOLLOW)).isFalse();
    assertThat(target.isSymbolicLink()).isTrue();
    assertThat(target.readSymbolicLink()).isEqualTo(PathFragment.create("link-target"));
  }

  @Test
  public void testReadContentWithLimit() throws IOException {
    createTestDirectoryTree();
    String str = "this is a test of readContentWithLimit method";
    FileSystemUtils.writeContent(file1, StandardCharsets.ISO_8859_1, str);
    assertThat(readStringFromFile(file1, 0)).isEmpty();
    assertThat(str.substring(0, 10)).isEqualTo(readStringFromFile(file1, 10));
    assertThat(str).isEqualTo(readStringFromFile(file1, 1000000));
  }

  private String readStringFromFile(Path file, int limit) throws IOException {
    byte[] bytes = FileSystemUtils.readContentWithLimit(file, limit);
    return new String(bytes, StandardCharsets.ISO_8859_1);
  }

  @Test
  public void testAppend() throws IOException {
    createTestDirectoryTree();
    FileSystemUtils.writeIsoLatin1(file1, "nobody says ");
    FileSystemUtils.writeIsoLatin1(file1, "mary had");
    FileSystemUtils.appendIsoLatin1(file1, "a little lamb");
    assertThat(new String(FileSystemUtils.readContentAsLatin1(file1)))
        .isEqualTo("mary had\na little lamb\n");
  }

  @Test
  public void testCopyFileAttributes() throws IOException {
    createTestDirectoryTree();
    Path originalFile = file1;
    byte[] content = new byte[] { 'a', 'b', 'c', 23, 42 };
    FileSystemUtils.writeContent(originalFile, content);
    file1.setLastModifiedTime(12345L);
    file1.setWritable(false);
    file1.setExecutable(false);

    Path copyTarget = file2;
    copyFile(originalFile, copyTarget);

    assertThat(file2.getLastModifiedTime()).isEqualTo(12345L);
    assertThat(file2.isExecutable()).isFalse();
    assertThat(file2.isWritable()).isFalse();

    file1.setWritable(true);
    file1.setExecutable(true);

    copyFile(originalFile, copyTarget);

    assertThat(file2.getLastModifiedTime()).isEqualTo(12345L);
    assertThat(file2.isExecutable()).isTrue();
    assertThat(file2.isWritable()).isTrue();
  }

  @Test
  public void testCopyFileThrowsExceptionIfTargetCantBeDeleted() throws IOException {
    createTestDirectoryTree();
    Path originalFile = file1;
    byte[] content = new byte[] { 'a', 'b', 'c', 23, 42 };
    FileSystemUtils.writeContent(originalFile, content);

    IOException ex = assertThrows(IOException.class, () -> copyFile(originalFile, aDir));
    assertThat(ex)
        .hasMessageThat()
        .isEqualTo(
            "error copying file: couldn't delete destination: " + aDir + " (Directory not empty)");
  }

  @Test
  public void testCopyTool() throws IOException {
    createTestDirectoryTree();
    Path originalFile = file1;
    byte[] content = new byte[] { 'a', 'b', 'c', 23, 42 };
    FileSystemUtils.writeContent(originalFile, content);

    Path copyTarget = copyTool(topDir.getRelative("file-1"), aDir.getRelative("file-1"));

    assertThat(FileSystemUtils.readContent(copyTarget)).isEqualTo(content);
    assertThat(copyTarget.isWritable()).isEqualTo(file1.isWritable());
    assertThat(copyTarget.isExecutable()).isEqualTo(file1.isExecutable());
    assertThat(copyTarget.getLastModifiedTime()).isEqualTo(file1.getLastModifiedTime());
  }

  @Test
  public void testCopyTreesBelow() throws IOException {
    createTestDirectoryTree();
    Path toPath = fileSystem.getPath("/copy-here");
    toPath.createDirectory();

    FileSystemUtils.copyTreesBelow(topDir, toPath, Symlinks.FOLLOW);
    checkTestDirectoryTreesBelow(toPath);
  }

  @Test
  public void testCopyTreesBelowWithOverriding() throws IOException {
    createTestDirectoryTree();
    Path toPath = fileSystem.getPath("/copy-here");
    toPath.createDirectory();
    toPath.getChild("file-2");

    FileSystemUtils.copyTreesBelow(topDir, toPath, Symlinks.FOLLOW);
    checkTestDirectoryTreesBelow(toPath);
  }

  @Test
  public void testCopyTreesBelowToSubtree() throws IOException {
    createTestDirectoryTree();
    IllegalArgumentException expected =
        assertThrows(
            IllegalArgumentException.class,
            () -> FileSystemUtils.copyTreesBelow(topDir, aDir, Symlinks.FOLLOW));
    assertThat(expected).hasMessageThat().isEqualTo("/top-dir/a-dir is a subdirectory of /top-dir");
  }

  @Test
  public void testCopyFileAsDirectoryTree() throws IOException {
    createTestDirectoryTree();
    IOException expected =
        assertThrows(
            IOException.class, () -> FileSystemUtils.copyTreesBelow(file1, aDir, Symlinks.FOLLOW));
    assertThat(expected).hasMessageThat().isEqualTo("/top-dir/file-1 (Not a directory)");
  }

  @Test
  public void testCopyTreesBelowToFile() throws IOException {
    createTestDirectoryTree();
    Path copyDir = fileSystem.getPath("/my-dir");
    Path copySubDir = fileSystem.getPath("/my-dir/subdir");
    FileSystemUtils.createDirectoryAndParents(copySubDir);
    IOException expected =
        assertThrows(
            IOException.class,
            () -> FileSystemUtils.copyTreesBelow(copyDir, file4, Symlinks.FOLLOW));
    assertThat(expected).hasMessageThat().isEqualTo("/file-4 (Not a directory)");
  }

  @Test
  public void testCopyTreesBelowFromUnexistingDir() throws IOException {
    createTestDirectoryTree();

    Path unexistingDir = fileSystem.getPath("/unexisting-dir");
    FileNotFoundException expected =
        assertThrows(
            FileNotFoundException.class,
            () -> FileSystemUtils.copyTreesBelow(unexistingDir, aDir, Symlinks.FOLLOW));
    assertThat(expected).hasMessageThat().isEqualTo("/unexisting-dir (No such file or directory)");
  }

  @Test
  public void testCopyTreesBelowNoFollowSymlinks() throws IOException {
    createTestDirectoryTree();
    PathFragment relative1 = file1.relativeTo(topDir);
    topDir.getRelative("relative-link").createSymbolicLink(relative1);
    PathFragment relativeInner = PathFragment.create("..").getRelative(relative1);
    bDir.getRelative("relative-inner-link").createSymbolicLink(relativeInner);
    PathFragment rootDirectory = PathFragment.create("/");
    topDir.getRelative("absolute-link").createSymbolicLink(rootDirectory);
    Path toPath = fileSystem.getPath("/copy-here");
    toPath.createDirectory();

    FileSystemUtils.copyTreesBelow(topDir, toPath, Symlinks.NOFOLLOW);
    Path copiedInnerDir = checkTestDirectoryTreesBelowExceptSymlinks(toPath);
    Path copiedLink1 = copiedInnerDir.getChild("link-1");
    assertThat(copiedLink1.exists()).isTrue();
    assertThat(copiedLink1.isSymbolicLink()).isTrue();
    assertThat(copiedLink1.readSymbolicLink()).isEqualTo(file4.asFragment());

    Path copiedDirLink = copiedInnerDir.getChild("dir-link");
    assertThat(copiedDirLink.exists()).isTrue();
    assertThat(copiedDirLink.isDirectory()).isTrue();
    assertThat(copiedDirLink.readSymbolicLink()).isEqualTo(bDir.asFragment());

    assertThat(toPath.getRelative("relative-link").readSymbolicLink()).isEqualTo(relative1);
    assertThat(
            toPath
                .getRelative(bDir.relativeTo(topDir))
                .getRelative("relative-inner-link")
                .readSymbolicLink())
        .isEqualTo(relativeInner);
    assertThat(toPath.getRelative("absolute-link").readSymbolicLink()).isEqualTo(rootDirectory);
  }

  @Test
  public void testTraverseTree() throws IOException {
    createTestDirectoryTree();

    Collection<Path> paths = traverseTree(topDir, p -> !p.getPathString().contains("a-dir"));
    assertThat(paths).containsExactly(file1, file2, bDir, file5);
  }

  @Test
  public void testTraverseTreeDeep() throws IOException {
    createTestDirectoryTree();

    Collection<Path> paths = traverseTree(topDir, ignored -> true);
    assertThat(paths).containsExactly(aDir,
        file3,
        innerDir,
        link1,
        file1,
        file2,
        dirLink,
        bDir,
        file5);
  }

  @Test
  public void testTraverseTreeLinkDir() throws IOException {
    // Use a new little tree for this test:
    //  top-dir/
    //    dir-link2 => linked-dir
    //  linked-dir/
    //    file
    topDir = fileSystem.getPath("/top-dir");
    Path dirLink2 = fileSystem.getPath("/top-dir/dir-link2");
    Path linkedDir = fileSystem.getPath("/linked-dir");
    Path linkedDirFile = fileSystem.getPath("/top-dir/dir-link2/file");

    topDir.createDirectory();
    linkedDir.createDirectory();
    dirLink2.createSymbolicLink(linkedDir);  // simple symlink
    FileSystemUtils.createEmptyFile(linkedDirFile);  // created through the link

    // traverseTree doesn't follow links:
    Collection<Path> paths = traverseTree(topDir, ignored -> true);
    assertThat(paths).containsExactly(dirLink2);

    paths = traverseTree(linkedDir, ignored -> true);
    assertThat(paths).containsExactly(fileSystem.getPath("/linked-dir/file"));
  }

  @Test
  public void testWriteIsoLatin1() throws Exception {
    Path file = fileSystem.getPath("/does/not/exist/yet.txt");
    FileSystemUtils.writeIsoLatin1(file, "Line 1", "Line 2", "Line 3");
    String expected = "Line 1\nLine 2\nLine 3\n";
    String actual = new String(FileSystemUtils.readContentAsLatin1(file));
    assertThat(actual).isEqualTo(expected);
  }

  @Test
  public void testWriteLinesAs() throws Exception {
    Path file = fileSystem.getPath("/does/not/exist/yet.txt");
    FileSystemUtils.writeLinesAs(file, UTF_8, "\u00F6"); // an oe umlaut
    byte[] expected = new byte[] {(byte) 0xC3, (byte) 0xB6, 0x0A};//"\u00F6\n";
    byte[] actual = FileSystemUtils.readContent(file);
    assertThat(actual).isEqualTo(expected);
  }

  @Test
  public void testUpdateContent() throws Exception {
    Path file = fileSystem.getPath("/test.txt");

    clock.advanceMillis(1000);

    byte[] content = new byte[] { 'a', 'b', 'c', 23, 42 };
    FileSystemUtils.maybeUpdateContent(file, content);
    byte[] actual = FileSystemUtils.readContent(file);
    assertThat(actual).isEqualTo(content);
    FileStatus stat = file.stat();
    assertThat(stat.getLastChangeTime()).isEqualTo(1000);
    assertThat(stat.getLastModifiedTime()).isEqualTo(1000);

    clock.advanceMillis(1000);

    // Update with same contents; should not write anything.
    FileSystemUtils.maybeUpdateContent(file, content);
    assertThat(actual).isEqualTo(content);
    stat = file.stat();
    assertThat(stat.getLastChangeTime()).isEqualTo(1000);
    assertThat(stat.getLastModifiedTime()).isEqualTo(1000);

    clock.advanceMillis(1000);

    // Update with different contents; file should be rewritten.
    content[0] = 'b';
    file.chmod(0400);  // Protect the file to ensure we can rewrite it.
    FileSystemUtils.maybeUpdateContent(file, content);
    actual = FileSystemUtils.readContent(file);
    assertThat(actual).isEqualTo(content);
    stat = file.stat();
    assertThat(stat.getLastChangeTime()).isEqualTo(3000);
    assertThat(stat.getLastModifiedTime()).isEqualTo(3000);
  }

  @Test
  public void testGetFileSystem() throws Exception {
    Path mountTable = fileSystem.getPath("/proc/mounts");
    FileSystemUtils.writeIsoLatin1(mountTable,
        "/dev/sda1 / ext2 blah 0 0",
        "/dev/mapper/_dev_sda6 /usr/local/google ext3 blah 0 0",
        "devshm /dev/shm tmpfs blah 0 0",
        "/dev/fuse /fuse/mnt fuse blah 0 0",
        "mtvhome22.nfs:/vol/mtvhome22/johndoe /home/johndoe nfs blah 0 0",
        "/dev/foo /foo dummy_foo blah 0 0",
        "/dev/foobar /foobar dummy_foobar blah 0 0",
        "proc proc proc rw,noexec,nosuid,nodev 0 0");
    Path path = fileSystem.getPath("/usr/local/google/_blaze");
    FileSystemUtils.createDirectoryAndParents(path);
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("ext3");

    // Should match the root "/"
    path = fileSystem.getPath("/usr/local/tmp");
    FileSystemUtils.createDirectoryAndParents(path);
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("ext2");

    // Make sure we don't consider /foobar matches /foo
    path = fileSystem.getPath("/foo");
    FileSystemUtils.createDirectoryAndParents(path);
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("dummy_foo");
    path = fileSystem.getPath("/foobar");
    FileSystemUtils.createDirectoryAndParents(path);
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("dummy_foobar");

    path = fileSystem.getPath("/dev/shm/blaze");
    FileSystemUtils.createDirectoryAndParents(path);
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("tmpfs");

    Path fusePath = fileSystem.getPath("/fuse/mnt/tmp");
    FileSystemUtils.createDirectoryAndParents(fusePath);
    assertThat(FileSystemUtils.getFileSystem(fusePath)).isEqualTo("fuse");

    // Create a symlink and make sure it gives the file system of the symlink target.
    path = fileSystem.getPath("/usr/local/google/_blaze/out");
    path.createSymbolicLink(fusePath);
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("fuse");

    // Non existent path should return "unknown"
    path = fileSystem.getPath("/does/not/exist");
    assertThat(FileSystemUtils.getFileSystem(path)).isEqualTo("unknown");
  }

  @Test
  public void testStartsWithAnySuccess() throws Exception {
    PathFragment a = PathFragment.create("a");
    assertThat(
            FileSystemUtils.startsWithAny(
                a, Arrays.asList(PathFragment.create("b"), PathFragment.create("a"))))
        .isTrue();
  }

  @Test
  public void testStartsWithAnyNotFound() throws Exception {
    PathFragment a = PathFragment.create("a");
    assertThat(
            FileSystemUtils.startsWithAny(
                a, Arrays.asList(PathFragment.create("b"), PathFragment.create("c"))))
        .isFalse();
  }

  @Test
  public void testIterateLines() throws Exception {
    Path file = fileSystem.getPath("/test.txt");
    FileSystemUtils.writeContent(file, ISO_8859_1, "a\nb");
    assertThat(Lists.newArrayList(FileSystemUtils.iterateLinesAsLatin1(file)))
        .isEqualTo(Arrays.asList("a", "b"));

    FileSystemUtils.writeContent(file, ISO_8859_1, "a\rb");
    assertThat(Lists.newArrayList(FileSystemUtils.iterateLinesAsLatin1(file)))
        .isEqualTo(Arrays.asList("a", "b"));

    FileSystemUtils.writeContent(file, ISO_8859_1, "a\r\nb");
    assertThat(Lists.newArrayList(FileSystemUtils.iterateLinesAsLatin1(file)))
        .isEqualTo(Arrays.asList("a", "b"));
  }

  @Test
  public void testEnsureSymbolicLinkDoesNotMakeUnnecessaryChanges() throws Exception {
    PathFragment target = PathFragment.create("/b");
    Path file = fileSystem.getPath("/a");
    file.createSymbolicLink(target);
    long prevTimeMillis = clock.currentTimeMillis();
    clock.advanceMillis(1000);
    FileSystemUtils.ensureSymbolicLink(file, target);
    long timestamp = file.getLastModifiedTime(Symlinks.NOFOLLOW);
    assertThat(timestamp).isEqualTo(prevTimeMillis);
  }

  @Test
  public void testCreateHardLinkForFile_Success() throws Exception {

    /* Original file exists and link file does not exist */
    Path originalPath = workingDir.getRelative("original");
    Path linkPath = workingDir.getRelative("link");
    FileSystemUtils.createEmptyFile(originalPath);
    FileSystemUtils.createHardLink(linkPath, originalPath);
    assertThat(originalPath.exists()).isTrue();
    assertThat(linkPath.exists()).isTrue();
    assertThat(fileSystem.stat(linkPath, false).getNodeId())
        .isEqualTo(fileSystem.stat(originalPath, false).getNodeId());
  }

  @Test
  public void testCreateHardLinkForEmptyDirectory_Success() throws Exception {

    Path originalDir = workingDir.getRelative("originalDir");
    Path linkPath = workingDir.getRelative("link");

    FileSystemUtils.createDirectoryAndParents(originalDir);

    /* Original directory is empty, no link to be created. */
    FileSystemUtils.createHardLink(linkPath, originalDir);
    assertThat(linkPath.exists()).isFalse();
  }

  @Test
  public void testCreateHardLinkForNonEmptyDirectory_Success() throws Exception {

    /* Test when original path is a directory */
    Path originalDir = workingDir.getRelative("originalDir");
    Path linkPath = workingDir.getRelative("link");
    Path originalPath1 = originalDir.getRelative("original1");
    Path originalPath2 = originalDir.getRelative("original2");
    Path originalPath3 = originalDir.getRelative("original3");
    Path linkPath1 = linkPath.getRelative("original1");
    Path linkPath2 = linkPath.getRelative("original2");
    Path linkPath3 = linkPath.getRelative("original3");

    FileSystemUtils.createDirectoryAndParents(originalDir);
    FileSystemUtils.createEmptyFile(originalPath1);
    FileSystemUtils.createEmptyFile(originalPath2);
    FileSystemUtils.createEmptyFile(originalPath3);

    /* Three link files created under linkPath */
    FileSystemUtils.createHardLink(linkPath, originalDir);
    assertThat(linkPath.exists()).isTrue();
    assertThat(linkPath1.exists()).isTrue();
    assertThat(linkPath2.exists()).isTrue();
    assertThat(linkPath3.exists()).isTrue();
    assertThat(fileSystem.stat(linkPath1, false).getNodeId())
        .isEqualTo(fileSystem.stat(originalPath1, false).getNodeId());
    assertThat(fileSystem.stat(linkPath2, false).getNodeId())
        .isEqualTo(fileSystem.stat(originalPath2, false).getNodeId());
    assertThat(fileSystem.stat(linkPath3, false).getNodeId())
        .isEqualTo(fileSystem.stat(originalPath3, false).getNodeId());
  }
}
