// Copyright 2019 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.buildtool;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.testutil.ManualClock;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.Symlinks;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests {@link SymlinkForest}. */
@RunWith(JUnit4.class)
public class SymlinkForestTest {
  private FileSystem fileSystem;

  private Path topDir;
  private Path file1;
  private Path file2;
  private Path aDir;

  // The execution root.
  private Path linkRoot;

  @Before
  public final void initializeFileSystem() throws Exception {
    ManualClock clock = new ManualClock();
    fileSystem = new InMemoryFileSystem(clock, DigestHashFunction.SHA256);
    linkRoot = fileSystem.getPath("/linkRoot");
    linkRoot.createDirectoryAndParents();
  }

  /*
   * 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");
    Path bDir = fileSystem.getPath("/top-dir/b-dir");
    Path file3 = fileSystem.getPath("/top-dir/a-dir/file-3");
    Path innerDir = fileSystem.getPath("/top-dir/a-dir/inner-dir");
    Path link1 = fileSystem.getPath("/top-dir/a-dir/inner-dir/link-1");
    Path dirLink = fileSystem.getPath("/top-dir/a-dir/inner-dir/dir-link");
    Path file4 = fileSystem.getPath("/file-4");
    Path 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 static PathFragment longestPathPrefix(String path, String... prefixStrs) {
    ImmutableSet.Builder<PackageIdentifier> prefixes = ImmutableSet.builder();
    for (String prefix : prefixStrs) {
      prefixes.add(PackageIdentifier.createInMainRepo(prefix));
    }
    PackageIdentifier longest =
        SymlinkForest.longestPathPrefix(PackageIdentifier.createInMainRepo(path), prefixes.build());
    return longest != null ? longest.getPackageFragment() : null;
  }

  private static Root externalSourceRoot(Root outputBase, String repoName) {
    return Root.fromPath(
        outputBase
            .asPath()
            .getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION)
            .getRelative(repoName));
  }

  @Test
  public void testLongestPathPrefix() {
    PathFragment a = PathFragment.create("A");
    assertThat(longestPathPrefix("A/b", "A", "B")).isEqualTo(a); // simple parent
    assertThat(longestPathPrefix("A", "A", "B")).isEqualTo(a); // self
    assertThat(longestPathPrefix("A/B/c", "A", "A/B"))
        .isEqualTo(a.getRelative("B")); // want longest
    assertThat(longestPathPrefix("C/b", "A", "B")).isNull(); // not found in other parents
    assertThat(longestPathPrefix("A", "A/B", "B")).isNull(); // not found in child
    assertThat(longestPathPrefix("A/B/C/d/e/f.h", "A/B/C", "B/C/d"))
        .isEqualTo(a.getRelative("B/C"));
    assertThat(longestPathPrefix("A/f.h", "", "B/C/d")).isEqualTo(PathFragment.EMPTY_FRAGMENT);
  }

  @Test
  public void testDeleteTreesBelowNotPrefixed() throws IOException {
    createTestDirectoryTree();
    new SymlinkForest(ImmutableMap.of(), topDir, "").deleteTreesBelowNotPrefixed(topDir, "file-");
    assertThat(file1.exists()).isTrue();
    assertThat(file2.exists()).isTrue();
    assertThat(aDir.exists()).isFalse();
  }

  // Create same package under two different roots
  private static PackageIdentifier createPkg(Root rootA, Root rootB, String pkg)
      throws IOException {
    if (rootA != null) {
      rootA.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(rootA.getRelative(pkg).getChild("file"));
    }
    if (rootB != null) {
      rootB.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(rootB.getRelative(pkg).getChild("file"));
    }
    return PackageIdentifier.createInMainRepo(pkg);
  }

  // Create package for external repo
  private static PackageIdentifier createExternalPkg(Root root, String repo, String pkg)
      throws IOException, LabelSyntaxException {
    if (root != null) {
      Path repoRoot =
          root.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION).getRelative(repo);
      repoRoot.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
    }
    return PackageIdentifier.create(RepositoryName.create("@" + repo), PathFragment.create(pkg));
  }

  // Create package for main repo
  private static PackageIdentifier createMainPkg(Root repoRoot, String pkg)
      throws IOException, LabelSyntaxException {
    if (repoRoot != null) {
      repoRoot.getRelative(pkg).createDirectoryAndParents();
      FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
    }
    return PackageIdentifier.create(RepositoryName.create("@"), PathFragment.create(pkg));
  }

  private static void assertLinksTo(Path fromRoot, Root toRoot, String relpart) throws IOException {
    assertLinksTo(fromRoot.getRelative(relpart), toRoot.getRelative(relpart));
  }

  private static void assertLinksTo(Path fromRoot, Path toRoot) throws IOException {
    assertWithMessage("stat: " + fromRoot.stat()).that(fromRoot.isSymbolicLink()).isTrue();
    assertThat(fromRoot.readSymbolicLink()).isEqualTo(toRoot.asFragment());
  }

  private static void assertLinksToExternalRepo(Path fromRoot, Root toRoot, String repoName)
      throws IOException {
    assertLinksTo(
        fromRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX.getRelative(repoName)),
        toRoot.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION).getRelative(repoName));
  }

  private static void assertIsDir(Path root, String relpart) {
    assertThat(root.getRelative(relpart).isDirectory(Symlinks.NOFOLLOW)).isTrue();
  }

  @Test
  public void testPlantLinkForestWithMultiplePackagePath() throws Exception {
    Root rootA = Root.fromPath(fileSystem.getPath("/A"));
    Root rootB = Root.fromPath(fileSystem.getPath("/B"));

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createPkg(rootA, rootB, "pkgA"), rootA)
            .put(createPkg(rootA, rootB, "dir1/pkgA"), rootA)
            .put(createPkg(rootA, rootB, "dir1/pkgB"), rootB)
            .put(createPkg(rootA, rootB, "dir2/pkg"), rootA)
            .put(createPkg(rootA, rootB, "dir2/pkg/pkg"), rootB)
            .put(createPkg(rootA, rootB, "pkgB"), rootB)
            .put(createPkg(rootA, rootB, "pkgB/dir/pkg"), rootA)
            .put(createPkg(rootA, rootB, "pkgB/pkg"), rootA)
            .put(createPkg(rootA, rootB, "pkgB/pkg/pkg"), rootA)
            .buildOrThrow();
    createPkg(rootA, rootB, "pkgB/dir"); // create a file in there

    Path linkRoot = fileSystem.getPath("/linkRoot");
    linkRoot.createDirectoryAndParents();
    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, rootA, "pkgA");
    assertIsDir(linkRoot, "dir1");
    assertLinksTo(linkRoot, rootA, "dir1/pkgA");
    assertLinksTo(linkRoot, rootB, "dir1/pkgB");
    assertIsDir(linkRoot, "dir2");
    assertIsDir(linkRoot, "dir2/pkg");
    assertLinksTo(linkRoot, rootA, "dir2/pkg/file");
    assertLinksTo(linkRoot, rootB, "dir2/pkg/pkg");
    assertIsDir(linkRoot, "pkgB");
    assertIsDir(linkRoot, "pkgB/dir");
    assertLinksTo(linkRoot, rootB, "pkgB/dir/file");
    assertLinksTo(linkRoot, rootA, "pkgB/dir/pkg");
    assertLinksTo(linkRoot, rootA, "pkgB/pkg");
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("pkgA"),
            linkRoot.getRelative("dir1/pkgA"),
            linkRoot.getRelative("dir1/pkgB"),
            linkRoot.getRelative("dir2/pkg/file"),
            linkRoot.getRelative("dir2/pkg/pkg"),
            linkRoot.getRelative("pkgB/file"),
            linkRoot.getRelative("pkgB/dir/file"),
            linkRoot.getRelative("pkgB/dir/pkg"),
            linkRoot.getRelative("pkgB/pkg"));
  }

  @Test
  public void testTopLevelPackage() throws Exception {
    Root rootX = Root.fromPath(fileSystem.getPath("/X"));
    Root rootY = Root.fromPath(fileSystem.getPath("/Y"));
    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createPkg(rootX, rootY, ""), rootX)
            .put(createPkg(rootX, rootY, "foo"), rootX)
            .buildOrThrow();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();
    assertLinksTo(linkRoot, rootX, "file");
    assertThat(plantedSymlinks)
        .containsExactly(linkRoot.getRelative("file"), linkRoot.getRelative("foo"));
  }

  @Test
  public void testPlantSymlinkForest() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    mainRepo.asPath().createDirectoryAndParents();
    linkRoot.createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir_main"), mainRepo)
            .put(createMainPkg(mainRepo, "dir_lib/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, ""), mainRepo)
            // Remote repo without top-level package.
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            // Remote repo with and without top-level package.
            .put(createExternalPkg(outputBase, "Y", ""), externalSourceRoot(outputBase, "Y"))
            .put(
                createExternalPkg(outputBase, "Y", "dir_y/pkg"),
                externalSourceRoot(outputBase, "Y"))
            // Only top-level pkg.
            .put(createExternalPkg(outputBase, "Z", ""), externalSourceRoot(outputBase, "Z"))
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir_main");
    assertLinksTo(linkRoot, mainRepo, "dir_lib");
    assertLinksTo(linkRoot, mainRepo, "file");
    assertLinksToExternalRepo(linkRoot, outputBase, "X");
    assertLinksToExternalRepo(linkRoot, outputBase, "Y");
    assertLinksToExternalRepo(linkRoot, outputBase, "Z");
    assertThat(
            linkRoot
                .getRelative(LabelConstants.EXTERNAL_PATH_PREFIX)
                .getRelative("Y/file")
                .exists())
        .isTrue();
    assertThat(
            linkRoot
                .getRelative(LabelConstants.EXTERNAL_PATH_PREFIX)
                .getRelative("Z/file")
                .exists())
        .isTrue();
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir_main"),
            linkRoot.getRelative("dir_lib"),
            linkRoot.getRelative("file"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/Y"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/Z"));
  }

  @Test
  public void test_withSiblingRepoLayout_plantSymlinkForest() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    mainRepo.asPath().createDirectoryAndParents();
    linkRoot.createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir_main"), mainRepo)
            .put(createMainPkg(mainRepo, "dir_lib/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, ""), mainRepo)
            // Remote repo without top-level package.
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            // Remote repo with and without top-level package.
            .put(createExternalPkg(outputBase, "Y", ""), externalSourceRoot(outputBase, "Y"))
            .put(
                createExternalPkg(outputBase, "Y", "dir_y/pkg"),
                externalSourceRoot(outputBase, "Y"))
            // Only top-level pkg.
            .put(createExternalPkg(outputBase, "Z", ""), externalSourceRoot(outputBase, "Z"))
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), true)
            .plantSymlinkForest();

    // Expected sibling repository layout (X, Y and Z are siblings of ws_name):
    //
    // .
    // ├── execroot
    // │   ├── ws_name { ... }
    // │   ├── X -> external/X
    // │   ├── Y -> external/Y
    // │   └── Z -> external/Z
    // └── external
    //     ├── X
    //     ├── Y
    //     └── Z

    assertLinksTo(linkRoot, mainRepo, "dir_main");
    assertLinksTo(linkRoot, mainRepo, "dir_lib");
    assertLinksTo(linkRoot, mainRepo, "file");
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("X"),
        outputBase.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION + "/X"));
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("Y"),
        outputBase.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION + "/Y"));
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("Z"),
        outputBase.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION + "/Z"));
    assertThat(linkRoot.getParentDirectory().getRelative("Y/file").exists()).isTrue();
    assertThat(linkRoot.getParentDirectory().getRelative("Z/file").exists()).isTrue();
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir_main"),
            linkRoot.getRelative("dir_lib"),
            linkRoot.getRelative("file"),
            linkRoot.getParentDirectory().getRelative("X"),
            linkRoot.getParentDirectory().getRelative("Y"),
            linkRoot.getParentDirectory().getRelative("Z"));
  }

  @Test
  public void testPlantSymlinkForestForMainRepo() throws Exception {
    // For the main repo, plantSymlinkForest function should only link all files and dirs under
    // main repo root that're presented in packageRootMap.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir4").createDirectoryAndParents();
    FileSystemUtils.createEmptyFile(mainRepo.getRelative("file"));

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, "dir3"), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .buildOrThrow();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    // dir4 and the file under main repo root should not be linked
    // because they are not presented in packageRootMap.
    assertThat(linkRoot.getChild("dir4").exists()).isFalse();
    assertThat(linkRoot.getChild("file").exists()).isFalse();
    assertLinksToExternalRepo(linkRoot, outputBase, "X");
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir1"),
            linkRoot.getRelative("dir2"),
            linkRoot.getRelative("dir3"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"));
  }

  @Test
  public void test_withSubdirRepoLayout_testExternalDirInMainRepoIsIgnored1() throws Exception {
    // Test external/ is ignored even when packages like "//external/foo" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, "dir3"), mainRepo)
            // external/ should not be linked even we have "//external/foo" package
            .put(createMainPkg(mainRepo, "external/foo"), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    assertLinksToExternalRepo(linkRoot, outputBase, "X");
    assertThat(outputBase.getRelative("external/foo").exists()).isFalse();
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir1"),
            linkRoot.getRelative("dir2"),
            linkRoot.getRelative("dir3"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"));
  }

  @Test
  public void test_withSubDirRepoLayout_testExternalDirInMainRepoIsIgnored2() throws Exception {
    // Test external/ is ignored when root package "//:" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir3").createDirectoryAndParents();
    mainRepo.getRelative("external/foo").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    assertLinksToExternalRepo(linkRoot, outputBase, "X");
    assertThat(outputBase.getRelative("external/foo").exists()).isFalse();
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir1"),
            linkRoot.getRelative("dir2"),
            linkRoot.getRelative("dir3"),
            linkRoot.getRelative("file"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"));
  }

  @Test
  public void test_withSiblingRepoLayout_testExternalDirInMainRepoExists() throws Exception {
    // Test external/ is ignored even when packages like "//external/foo" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(createMainPkg(mainRepo, "dir3"), mainRepo)
            // external/ should not be linked even we have "//external/foo" package
            .put(createMainPkg(mainRepo, "external/foo"), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), true)
            .plantSymlinkForest();

    // Expected output base layout with sibling repositories in the execroot where
    // ws_name and X are siblings:
    //
    // /ob
    // ├── execroot
    // │   ├── ws_name
    // │   │   ├── dir1
    // │   │   │   └── pkg
    // │   │   │       └── foo -> /my_repo/dir1/pkg/foo
    // │   │   ├── dir2
    // │   │   │   └── pkg -> /my_repo/dir2/pkg
    // │   │   ├── dir3 -> /my_repo/dir3
    // │   │   └── external -> /my_repo/external
    // │   └── X -> /ob/external/X
    // └── external
    //     └── X

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");

    assertThat(
            outputBase
                .getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION)
                .getRelative("X")
                .exists())
        .isTrue();
    assertThat(outputBase.getRelative("execroot/X").exists()).isTrue();
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("X"), // Sibling of the main repo.
        outputBase.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION).getRelative("X"));

    assertThat(linkRoot.getRelative("external/foo").exists()).isTrue();

    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir1"),
            linkRoot.getRelative("dir2"),
            linkRoot.getRelative("dir3"),
            linkRoot.getRelative("external"), // Symlinked to the main repo's top level external dir
            linkRoot.getParentDirectory().getRelative("X")); // Symlinked to /ob/external/X
  }

  @Test
  public void test_withSiblingRepoLayoutAndRootPackageInRoots_testExternalDirInMainRepoExists()
      throws Exception {
    // Test external/ is ignored when root package "//:" is specified.
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    mainRepo.getRelative("external/foo").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .buildOrThrow();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap, linkRoot, TestConstants.PRODUCT_NAME, ImmutableSortedSet.of(), true)
            .plantSymlinkForest();

    // Expected output base layout with sibling repositories in the execroot where
    // ws_name and X are siblings:
    //
    // /ob
    // ├── execroot
    // │   ├── ws_name
    // │   │   └── external -> /my_repo/external
    // │   └── X -> /ob/external/X
    // └── external
    //     └── X

    assertThat(
            outputBase
                .getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION)
                .getRelative("X")
                .exists())
        .isTrue();
    assertThat(outputBase.getRelative("execroot/X").exists()).isTrue();
    assertLinksTo(
        linkRoot.getParentDirectory().getRelative("X"), // Sibling of the main repo.
        outputBase.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION).getRelative("X"));

    assertThat(linkRoot.getRelative("external/foo").exists()).isTrue();

    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getParentDirectory().getRelative("X"),
            linkRoot.getRelative("file"), // created by createMainPkg test setup
            linkRoot.getRelative("external") // symlink to main repo's top level external directory
            );
  }

  @Test
  public void testExternalPackage() throws Exception {
    Path linkRoot = fileSystem.getPath("/linkRoot");
    linkRoot.createDirectoryAndParents();

    Root root = Root.fromPath(fileSystem.getPath("/src"));
    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            // Virtual root, shouldn't actually be linked in.
            .put(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER, root)
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of(),
                false)
            .plantSymlinkForest();
    assertThat(linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX).exists()).isFalse();
    assertThat(plantedSymlinks).isEmpty();
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootAllInMainRepo() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir3").createDirectoryAndParents();
    mainRepo.getRelative("build").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .build();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of("build"),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksTo(linkRoot, mainRepo, "dir3");
    assertLinksToExternalRepo(linkRoot, outputBase, "X");
    assertThat(linkRoot.getChild("build").exists()).isFalse();
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("file"),
            linkRoot.getRelative("dir1"),
            linkRoot.getRelative("dir2"),
            linkRoot.getRelative("dir3"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"));
  }

  @Test
  public void testNotSymlinkedDirectoriesNotDeletedBetweenCommands() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("build").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg"), mainRepo)
            // Empty package will cause every top-level files to be linked, except external/
            .put(createMainPkg(mainRepo, ""), mainRepo)
            .build();

    SymlinkForest symlinkForest =
        new SymlinkForest(
            packageRootMap,
            linkRoot,
            TestConstants.PRODUCT_NAME,
            ImmutableSortedSet.of("build"),
            false);
    symlinkForest.plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertThat(linkRoot.getChild("build").exists()).isFalse();

    // Create some file in 'build' directory under exec root.
    Path notSymlinkedDir = linkRoot.getChild("build");
    notSymlinkedDir.createDirectoryAndParents();

    byte[] bytes = "text".getBytes(StandardCharsets.ISO_8859_1);
    Path childPath = notSymlinkedDir.getChild("child.txt");
    FileSystemUtils.writeContent(childPath, bytes);

    symlinkForest.plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    // Exists because it was explicitly created.
    assertThat(linkRoot.getChild("build").exists()).isTrue();
    // The presence of the manually added file indicates that SymlinkForest did not delete
    // the directory it's in.
    assertThat(childPath.exists()).isTrue();
    assertThat(FileSystemUtils.readContent(childPath, StandardCharsets.ISO_8859_1))
        .isEqualTo("text");
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootPartialMainRepo1() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    mainRepo.getRelative("dir3").createDirectoryAndParents();
    mainRepo.getRelative("build").createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1/pkg/foo"), mainRepo)
            .put(createMainPkg(mainRepo, "dir2/pkg"), mainRepo)
            .put(
                createExternalPkg(outputBase, "X", "dir_x/pkg"),
                externalSourceRoot(outputBase, "X"))
            .buildOrThrow();

    ImmutableList<Path> plantedSymlinks =
        new SymlinkForest(
                packageRootMap,
                linkRoot,
                TestConstants.PRODUCT_NAME,
                ImmutableSortedSet.of("build"),
                false)
            .plantSymlinkForest();

    assertLinksTo(linkRoot, mainRepo, "dir1");
    assertLinksTo(linkRoot, mainRepo, "dir2");
    assertLinksToExternalRepo(linkRoot, outputBase, "X");
    assertThat(linkRoot.getChild("build").exists()).isFalse();
    // Not part of the package roots.
    assertThat(linkRoot.getChild("dir3").exists()).isFalse();
    assertThat(plantedSymlinks)
        .containsExactly(
            linkRoot.getRelative("dir1"),
            linkRoot.getRelative("dir2"),
            linkRoot.getRelative(LabelConstants.EXTERNAL_PATH_PREFIX + "/X"));
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootPartialMainRepo2() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.of(createMainPkg(mainRepo, "build"), mainRepo);

    AbruptExitException exception =
        assertThrows(
            AbruptExitException.class,
            () ->
                new SymlinkForest(
                        packageRootMap,
                        linkRoot,
                        TestConstants.PRODUCT_NAME,
                        ImmutableSortedSet.of("build"),
                        false)
                    .plantSymlinkForest());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Directories specified with toplevel_output_directories should be "
                + "ignored and can not be used as sources.");
  }

  @Test
  public void testNotSymlinkedDirectoriesInExecRootMultiplePackageRoots() throws Exception {
    Root outputBase = Root.fromPath(fileSystem.getPath("/ob"));
    Root mainRepo = Root.fromPath(fileSystem.getPath("/my_repo"));
    Root otherRepo = Root.fromPath(fileSystem.getPath("/other_repo"));
    Path linkRoot = outputBase.getRelative("execroot/ws_name");

    mainRepo.getRelative("build").createDirectoryAndParents();

    linkRoot.createDirectoryAndParents();
    mainRepo.asPath().createDirectoryAndParents();
    otherRepo.asPath().createDirectoryAndParents();

    ImmutableMap<PackageIdentifier, Root> packageRootMap =
        ImmutableMap.<PackageIdentifier, Root>builder()
            .put(createMainPkg(mainRepo, "dir1"), mainRepo)
            .put(createMainPkg(otherRepo, "dir2"), otherRepo)
            .buildOrThrow();

    AbruptExitException exception =
        assertThrows(
            AbruptExitException.class,
            () ->
                new SymlinkForest(
                        packageRootMap,
                        linkRoot,
                        TestConstants.PRODUCT_NAME,
                        ImmutableSortedSet.of("build"),
                        false)
                    .plantSymlinkForest());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "toplevel_output_directories is not supported together "
                + "with --package_path option.");
  }
}
