// 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.fail;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
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");
    try {
      BlazeTestUtils.changeModtime(file);
      fail();
    } catch (FileNotFoundException e) {
      /* ok */
    }
    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);

    try {
      copyFile(originalFile, aDir);
      fail();
    } catch (IOException ex) {
      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();
    try {
      FileSystemUtils.copyTreesBelow(topDir, aDir, Symlinks.FOLLOW);
      fail("Should not be able to copy a directory to a subdir");
    } catch (IllegalArgumentException expected) {
      assertThat(expected)
          .hasMessageThat()
          .isEqualTo("/top-dir/a-dir is a subdirectory of /top-dir");
    }
  }

  @Test
  public void testCopyFileAsDirectoryTree() throws IOException {
    createTestDirectoryTree();
    try {
      FileSystemUtils.copyTreesBelow(file1, aDir, Symlinks.FOLLOW);
      fail("Should not be able to copy a file with copyDirectory method");
    } catch (IOException expected) {
      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);
    try {
      FileSystemUtils.copyTreesBelow(copyDir, file4, Symlinks.FOLLOW);
      fail("Should not be able to copy a directory to a file");
    } catch (IOException expected) {
      assertThat(expected).hasMessageThat().isEqualTo("/file-4 (Not a directory)");
    }
  }

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

    try {
      Path unexistingDir = fileSystem.getPath("/unexisting-dir");
      FileSystemUtils.copyTreesBelow(unexistingDir, aDir, Symlinks.FOLLOW);
      fail("Should not be able to copy from an unexisting path");
    } catch (FileNotFoundException expected) {
      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, new Predicate<Path>() {
      @Override
      public boolean apply(Path p) {
        return !p.getPathString().contains("a-dir");
      }
    });
    assertThat(paths).containsExactly(file1, file2, bDir, file5);
  }

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

    Collection<Path> paths = traverseTree(topDir,
        Predicates.alwaysTrue());
    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, Predicates.alwaysTrue());
    assertThat(paths).containsExactly(dirLink2);

    paths = traverseTree(linkedDir, Predicates.alwaysTrue());
    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());
  }
}
