// Copyright 2015 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.skyframe;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;

import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ServerDirectories;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.bazel.bzlmod.BzlmodRepoRuleValue;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.io.FileSymlinkCycleUniquenessFunction;
import com.google.devtools.build.lib.packages.BuildFileName;
import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.packages.WorkspaceFileValue;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.rules.repository.LocalRepositoryFunction;
import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule;
import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy;
import com.google.devtools.build.lib.skyframe.PackageLookupValue.ErrorReason;
import com.google.devtools.build.lib.skyframe.PackageLookupValue.IncorrectRepositoryReferencePackageLookupValue;
import com.google.devtools.build.lib.testutil.FoundationTestCase;
import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
import com.google.devtools.build.lib.vfs.FileStateKey;
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.RootedPath;
import com.google.devtools.build.lib.vfs.SyscallCache;
import com.google.devtools.build.skyframe.EvaluationContext;
import com.google.devtools.build.skyframe.EvaluationResult;
import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
import com.google.devtools.build.skyframe.MemoizingEvaluator;
import com.google.devtools.build.skyframe.RecordingDifferencer;
import com.google.devtools.build.skyframe.SequencedRecordingDifferencer;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import net.starlark.java.eval.StarlarkSemantics;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** Tests for {@link PackageLookupFunction}. */
public abstract class PackageLookupFunctionTest extends FoundationTestCase {
  private AtomicReference<ImmutableSet<PackageIdentifier>> deletedPackages;
  private MemoizingEvaluator evaluator;
  private RecordingDifferencer differencer;
  private Path emptyPackagePath;
  private static final String IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING = "config/ignored.txt";

  protected abstract CrossRepositoryLabelViolationStrategy crossRepositoryLabelViolationStrategy();

  @Before
  public final void setUp() throws Exception {
    emptyPackagePath = rootDirectory.getRelative("somewhere/else");
    scratch.file("parentpackage/BUILD");

    AnalysisMock analysisMock = AnalysisMock.get();
    AtomicReference<PathPackageLocator> pkgLocator =
        new AtomicReference<>(
            new PathPackageLocator(
                outputBase,
                ImmutableList.of(Root.fromPath(emptyPackagePath), Root.fromPath(rootDirectory)),
                BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY));
    deletedPackages = new AtomicReference<>(ImmutableSet.of());
    BlazeDirectories directories =
        new BlazeDirectories(
            new ServerDirectories(rootDirectory, outputBase, rootDirectory),
            rootDirectory,
            /* defaultSystemJavabase= */ null,
            analysisMock.getProductName());
    ExternalFilesHelper externalFilesHelper = ExternalFilesHelper.createForTesting(
        pkgLocator, ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS, directories);

    Map<SkyFunctionName, SkyFunction> skyFunctions = new HashMap<>();
    skyFunctions.put(
        SkyFunctions.PACKAGE_LOOKUP,
        new PackageLookupFunction(
            deletedPackages,
            crossRepositoryLabelViolationStrategy(),
            BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY,
            BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));
    skyFunctions.put(SkyFunctions.PACKAGE, PackageFunction.newBuilder().build());
    skyFunctions.put(
        FileStateKey.FILE_STATE,
        new FileStateFunction(
            Suppliers.ofInstance(new TimestampGranularityMonitor(BlazeClock.instance())),
            SyscallCache.NO_CACHE,
            externalFilesHelper));
    skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator, directories));
    skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction());
    skyFunctions.put(
        SkyFunctions.DIRECTORY_LISTING_STATE,
        new DirectoryListingStateFunction(externalFilesHelper, SyscallCache.NO_CACHE));
    skyFunctions.put(
        SkyFunctions.IGNORED_PACKAGE_PREFIXES,
        new IgnoredPackagePrefixesFunction(
            PathFragment.create(IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING)));
    RuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider();
    skyFunctions.put(
        WorkspaceFileValue.WORKSPACE_FILE,
        new WorkspaceFileFunction(
            ruleClassProvider,
            analysisMock
                .getPackageFactoryBuilderForTesting(directories)
                .build(ruleClassProvider, fileSystem),
            directories,
            /*bzlLoadFunctionForInlining=*/ null));
    skyFunctions.put(
        SkyFunctions.EXTERNAL_PACKAGE,
        new ExternalPackageFunction(BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));
    skyFunctions.put(
        SkyFunctions.LOCAL_REPOSITORY_LOOKUP,
        new LocalRepositoryLookupFunction(BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));
    skyFunctions.put(
        FileSymlinkCycleUniquenessFunction.NAME, new FileSymlinkCycleUniquenessFunction());

    ImmutableMap<String, RepositoryFunction> repositoryHandlers =
        ImmutableMap.of(LocalRepositoryRule.NAME, new LocalRepositoryFunction());
    skyFunctions.put(
        SkyFunctions.REPOSITORY_DIRECTORY,
        new RepositoryDelegatorFunction(
            repositoryHandlers,
            null,
            new AtomicBoolean(true),
            ImmutableMap::of,
            directories,
            BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));
    skyFunctions.put(
        SkyFunctions.REPOSITORY_MAPPING,
        new SkyFunction() {
          @Override
          public SkyValue compute(SkyKey skyKey, Environment env) {
            return RepositoryMappingValue.VALUE_FOR_ROOT_MODULE_WITHOUT_REPOS;
          }
        });
    skyFunctions.put(
        BzlmodRepoRuleValue.BZLMOD_REPO_RULE,
        new SkyFunction() {
          @Override
          public SkyValue compute(SkyKey skyKey, Environment env) {
            return BzlmodRepoRuleValue.REPO_RULE_NOT_FOUND_VALUE;
          }
        });

    differencer = new SequencedRecordingDifferencer();
    evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer);
    PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID());
    PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
    PrecomputedValue.STARLARK_SEMANTICS.set(differencer, StarlarkSemantics.DEFAULT);
    RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set(differencer, ImmutableMap.of());
    RepositoryDelegatorFunction.FORCE_FETCH.set(
        differencer, RepositoryDelegatorFunction.FORCE_FETCH_DISABLED);
    RepositoryDelegatorFunction.VENDOR_DIRECTORY.set(differencer, Optional.empty());

    RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE.set(
        differencer, Optional.empty());
  }

  protected PackageLookupValue lookupPackage(String packageName) throws InterruptedException {
    return lookupPackage(PackageIdentifier.createInMainRepo(packageName));
  }

  protected PackageLookupValue lookupPackage(PackageIdentifier packageId)
      throws InterruptedException {
    SkyKey key = PackageLookupValue.key(packageId);
    return lookupPackage(key).get(key);
  }

  protected EvaluationResult<PackageLookupValue> lookupPackage(SkyKey packageIdentifierSkyKey)
      throws InterruptedException {
    EvaluationContext evaluationContext =
        EvaluationContext.newBuilder()
            .setKeepGoing(false)
            .setParallelism(SkyframeExecutor.DEFAULT_THREAD_COUNT)
            .setEventHandler(NullEventHandler.INSTANCE)
            .build();
    return evaluator.evaluate(ImmutableList.of(packageIdentifierSkyKey), evaluationContext);
  }

  @Test
  public void testNoBuildFile() throws Exception {
    scratch.file("parentpackage/nobuildfile/foo.txt");
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/nobuildfile");
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.NO_BUILD_FILE);
    assertThat(packageLookupValue.getErrorMsg()).isNotNull();
  }

  @Test
  public void testNoBuildFileAndNoParentPackage() throws Exception {
    scratch.file("noparentpackage/foo.txt");
    PackageLookupValue packageLookupValue = lookupPackage("noparentpackage");
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.NO_BUILD_FILE);
    assertThat(packageLookupValue.getErrorMsg()).isNotNull();
  }

  @Test
  public void testDeletedPackage() throws Exception {
    scratch.file("parentpackage/deletedpackage/BUILD");
    deletedPackages.set(ImmutableSet.of(
        PackageIdentifier.createInMainRepo("parentpackage/deletedpackage")));
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/deletedpackage");
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.DELETED_PACKAGE);
    assertThat(packageLookupValue.getErrorMsg()).isNotNull();
  }

  @Test
  public void testIgnoredPackage() throws Exception {
    scratch.file("ignored/subdir/BUILD");
    scratch.file("ignored/BUILD");
    Path ignored = scratch.overwriteFile(IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING, "ignored");

    ImmutableSet<String> pkgs = ImmutableSet.of("ignored/subdir", "ignored");
    for (String pkg : pkgs) {
      PackageLookupValue packageLookupValue = lookupPackage(pkg);
      assertThat(packageLookupValue.packageExists()).isFalse();
      assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.DELETED_PACKAGE);
      assertThat(packageLookupValue.getErrorMsg()).isNotNull();
    }

    scratch.overwriteFile(IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING, "not_ignored");
    RootedPath rootedIgnoreFile =
        RootedPath.toRootedPath(
            Root.fromPath(ignored.getParentDirectory().getParentDirectory()),
            PathFragment.create("config/ignored.txt"));
    differencer.invalidate(ImmutableSet.of(FileStateValue.key(rootedIgnoreFile)));
    for (String pkg : pkgs) {
      PackageLookupValue packageLookupValue = lookupPackage(pkg);
      assertThat(packageLookupValue.packageExists()).isTrue();
    }
  }

  @Test
  public void testInvalidPackageName() throws Exception {
    scratch.file("parentpackage/invalidpackagename:42/BUILD");
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/invalidpackagename:42");
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.INVALID_PACKAGE_NAME);
    assertThat(packageLookupValue.getErrorMsg()).isNotNull();
  }

  @Test
  public void testDirectoryNamedBuild() throws Exception {
    scratch.dir("parentpackage/isdirectory/BUILD");
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/isdirectory");
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.NO_BUILD_FILE);
    assertThat(packageLookupValue.getErrorMsg()).isNotNull();
  }

  @Test
  public void testEverythingIsGood_BUILD() throws Exception {
    scratch.file("parentpackage/everythinggood/BUILD");
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/everythinggood");
    assertThat(packageLookupValue.packageExists()).isTrue();
    assertThat(packageLookupValue.getRoot()).isEqualTo(Root.fromPath(rootDirectory));
    assertThat(packageLookupValue.getBuildFileName()).isEqualTo(BuildFileName.BUILD);
  }

  @Test
  public void testEverythingIsGood_BUILD_bazel() throws Exception {
    scratch.file("parentpackage/everythinggood/BUILD.bazel");
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/everythinggood");
    assertThat(packageLookupValue.packageExists()).isTrue();
    assertThat(packageLookupValue.getRoot()).isEqualTo(Root.fromPath(rootDirectory));
    assertThat(packageLookupValue.getBuildFileName()).isEqualTo(BuildFileName.BUILD_DOT_BAZEL);
  }

  @Test
  public void testEverythingIsGood_both() throws Exception {
    scratch.file("parentpackage/everythinggood/BUILD");
    scratch.file("parentpackage/everythinggood/BUILD.bazel");
    PackageLookupValue packageLookupValue = lookupPackage("parentpackage/everythinggood");
    assertThat(packageLookupValue.packageExists()).isTrue();
    assertThat(packageLookupValue.getRoot()).isEqualTo(Root.fromPath(rootDirectory));
    assertThat(packageLookupValue.getBuildFileName()).isEqualTo(BuildFileName.BUILD_DOT_BAZEL);
  }

  @Test
  public void testBuildFilesInMultiplePackagePaths() throws Exception {
    scratch.file(emptyPackagePath.getPathString() + "/foo/BUILD");
    scratch.file("foo/BUILD.bazel");

    // BUILD file in the first package path should be preferred to BUILD.bazel in the second.
    PackageLookupValue packageLookupValue = lookupPackage("foo");
    assertThat(packageLookupValue.packageExists()).isTrue();
    assertThat(packageLookupValue.getRoot()).isEqualTo(Root.fromPath(emptyPackagePath));
    assertThat(packageLookupValue.getBuildFileName()).isEqualTo(BuildFileName.BUILD);
  }

  @Test
  public void testEmptyPackageName() throws Exception {
    scratch.file("BUILD");
    PackageLookupValue packageLookupValue = lookupPackage("");
    assertThat(packageLookupValue.packageExists()).isTrue();
    assertThat(packageLookupValue.getRoot()).isEqualTo(Root.fromPath(rootDirectory));
    assertThat(packageLookupValue.getBuildFileName()).isEqualTo(BuildFileName.BUILD);
  }

  @Test
  public void testWorkspaceLookup() throws Exception {
    scratch.overwriteFile("WORKSPACE");
    PackageLookupValue packageLookupValue = lookupPackage(
        PackageIdentifier.createInMainRepo("external"));
    assertThat(packageLookupValue.packageExists()).isTrue();
    assertThat(packageLookupValue.getRoot()).isEqualTo(Root.fromPath(rootDirectory));
  }

  @Test
  public void invisibleRepo_main() throws Exception {
    scratch.file("BUILD");
    PackageLookupValue packageLookupValue =
        lookupPackage(
            PackageIdentifier.create(
                RepositoryName.MAIN.toNonVisible(RepositoryName.BAZEL_TOOLS),
                PathFragment.EMPTY_FRAGMENT));
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.REPOSITORY_NOT_FOUND);
    assertThat(packageLookupValue.getErrorMsg()).contains("No repository visible as");
  }

  @Test
  public void invisibleRepo_nonMain() throws Exception {
    scratch.overwriteFile("WORKSPACE", "local_repository(name='local', path='local/repo')");
    scratch.file("local/repo/WORKSPACE");
    scratch.file("local/repo/BUILD");

    PackageLookupValue packageLookupValue =
        lookupPackage(
            PackageIdentifier.create(
                RepositoryName.createUnvalidated("local").toNonVisible(RepositoryName.BAZEL_TOOLS),
                PathFragment.EMPTY_FRAGMENT));
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.REPOSITORY_NOT_FOUND);
    assertThat(packageLookupValue.getErrorMsg()).contains("No repository visible as");
  }

  @Test
  public void testPackageLookupValueHashCodeAndEqualsContract() {
    Root root1 = Root.fromPath(rootDirectory.getRelative("root1"));
    Root root2 = Root.fromPath(rootDirectory.getRelative("root2"));
    // Our (seeming) duplication of parameters here is intentional. Some of the subclasses of
    // PackageLookupValue are supposed to have reference equality semantics, and some are supposed
    // to have logical equality semantics.
    new EqualsTester()
        .addEqualityGroup(
            PackageLookupValue.success(root1, BuildFileName.BUILD),
            PackageLookupValue.success(root1, BuildFileName.BUILD))
        .addEqualityGroup(
            PackageLookupValue.success(root2, BuildFileName.BUILD),
            PackageLookupValue.success(root2, BuildFileName.BUILD))
        .addEqualityGroup(
            PackageLookupValue.success(root2, BuildFileName.BUILD, /* hasProjectFile= */ true))
        .addEqualityGroup(
            PackageLookupValue.NO_BUILD_FILE_VALUE, PackageLookupValue.NO_BUILD_FILE_VALUE)
        .addEqualityGroup(
            PackageLookupValue.DELETED_PACKAGE_VALUE, PackageLookupValue.DELETED_PACKAGE_VALUE)
        .addEqualityGroup(
            PackageLookupValue.invalidPackageName("nope1"),
            PackageLookupValue.invalidPackageName("nope1"))
        .addEqualityGroup(
            PackageLookupValue.invalidPackageName("nope2"),
            PackageLookupValue.invalidPackageName("nope2"))
        .testEquals();
  }

  protected void createAndCheckInvalidPackageLabel(boolean expectedPackageExists) throws Exception {
    scratch.overwriteFile("WORKSPACE", "local_repository(name='local', path='local/repo')");
    scratch.file("local/repo/WORKSPACE");
    scratch.file("local/repo/BUILD");

    // First, use the correct label.
    PackageLookupValue packageLookupValue =
        lookupPackage(PackageIdentifier.create("local", PathFragment.EMPTY_FRAGMENT));
    assertThat(packageLookupValue.packageExists()).isTrue();

    // Then, use the incorrect label.
    packageLookupValue = lookupPackage(PackageIdentifier.createInMainRepo("local/repo"));
    assertThat(packageLookupValue.packageExists()).isEqualTo(expectedPackageExists);
  }

  /**
   * Runs all tests in the base {@link PackageLookupFunctionTest} class with the {@link
   * CrossRepositoryLabelViolationStrategy#IGNORE} enum set, and also additional tests specific to
   * that setting.
   */
  @RunWith(JUnit4.class)
  public static class IgnoreLabelViolationsTest extends PackageLookupFunctionTest {
    @Override
    protected CrossRepositoryLabelViolationStrategy crossRepositoryLabelViolationStrategy() {
      return CrossRepositoryLabelViolationStrategy.IGNORE;
    }

    // Add any ignore-specific tests here.

    @Test
    public void testInvalidPackageLabelIsIgnored() throws Exception {
      createAndCheckInvalidPackageLabel(true);
    }
  }

  /**
   * Runs all tests in the base {@link PackageLookupFunctionTest} class with the {@link
   * CrossRepositoryLabelViolationStrategy#ERROR} enum set, and also additional tests specific to
   * that setting.
   */
  @RunWith(JUnit4.class)
  public static class ErrorLabelViolationsTest extends PackageLookupFunctionTest {
    @Override
    protected CrossRepositoryLabelViolationStrategy crossRepositoryLabelViolationStrategy() {
      return CrossRepositoryLabelViolationStrategy.ERROR;
    }

    // Add any error-specific tests here.

    @Test
    public void testInvalidPackageLabelIsError() throws Exception {
      createAndCheckInvalidPackageLabel(false);
    }

    @Test
    public void testSymlinkCycleInWorkspace() throws Exception {
      scratch.overwriteFile("WORKSPACE", "local_repository(name='local', path='local/repo')");
      Path localRepoWorkspace = scratch.resolve("local/repo/WORKSPACE");
      Path localRepoWorkspaceLink = scratch.resolve("local/repo/WORKSPACE.link");
      localRepoWorkspace.getParentDirectory().createDirectoryAndParents();
      localRepoWorkspaceLink.getParentDirectory().createDirectoryAndParents();
      localRepoWorkspace.createSymbolicLink(localRepoWorkspaceLink);
      localRepoWorkspaceLink.createSymbolicLink(localRepoWorkspace);
      scratch.file("local/repo/BUILD");

      SkyKey skyKey = PackageLookupValue.key(PackageIdentifier.createInMainRepo("local/repo"));
      EvaluationResult<PackageLookupValue> result = lookupPackage(skyKey);
      assertThatEvaluationResult(result)
          .hasErrorEntryForKeyThat(skyKey)
          .hasExceptionThat()
          .isInstanceOf(BuildFileNotFoundException.class);
      assertThatEvaluationResult(result)
          .hasErrorEntryForKeyThat(skyKey)
          .hasExceptionThat()
          .hasMessageThat()
          .isEqualTo(
              "no such package 'local/repo': Unable to determine the local repository for "
                  + "directory /workspace/local/repo");
    }
  }

  /** Tests for detection of invalid package identifiers for local repositories. */
  @RunWith(Parameterized.class)
  public static class CorrectedLocalRepositoryTest extends PackageLookupFunctionTest {

    /**
     * Create parameters for this test. The contents are:
     *
     * <ol>
     *   <li>description
     *   <li>repository path
     *   <li>package path - under the repository
     *   <li>expected corrected package identifier
     * </ol>
     */
    @Parameters(name = "{0}")
    public static List<Object[]> parameters() {
      List<Object[]> params = new ArrayList<>();

      params.add(new String[] {"simpleRepo_emptyPackage", "local", "", "@@local//"});
      params.add(new String[] {"simpleRepo_singlePackage", "local", "package", "@@local//package"});
      params.add(
          new String[] {
            "simpleRepo_subPackage", "local", "package/subpackage", "@@local//package/subpackage"
          });
      params.add(new String[] {"deepRepo_emptyPackage", "local/repo", "", "@@local//"});
      params.add(new String[] {"deepRepo_subPackage", "local/repo", "package", "@@local//package"});

      return params;
    }

    private final String repositoryPath;
    private final String packagePath;
    private final String expectedCorrectedPackageIdentifier;

    public CorrectedLocalRepositoryTest(
        String unusedDescription,
        String repositoryPath,
        String packagePath,
        String expectedCorrectedPackageIdentifier) {
      this.repositoryPath = repositoryPath;
      this.packagePath = packagePath;
      this.expectedCorrectedPackageIdentifier = expectedCorrectedPackageIdentifier;
    }

    @Override
    protected CrossRepositoryLabelViolationStrategy crossRepositoryLabelViolationStrategy() {
      return CrossRepositoryLabelViolationStrategy.ERROR;
    }

    @Test
    public void testCorrectPackageDetection_relativePath() throws Exception {
      scratch.overwriteFile(
          "WORKSPACE", "local_repository(name='local', path='" + repositoryPath + "')");
      scratch.file(PathFragment.create(repositoryPath).getRelative("WORKSPACE").getPathString());
      scratch.file(
          PathFragment.create(repositoryPath)
              .getRelative(packagePath)
              .getRelative("BUILD")
              .getPathString());

      PackageIdentifier packageIdentifier =
          PackageIdentifier.createInMainRepo(
              PathFragment.create(repositoryPath).getRelative(packagePath));
      PackageLookupValue packageLookupValue = lookupPackage(packageIdentifier);
      assertThat(packageLookupValue.packageExists()).isFalse();
      assertThat(packageLookupValue)
          .isInstanceOf(IncorrectRepositoryReferencePackageLookupValue.class);

      IncorrectRepositoryReferencePackageLookupValue incorrectPackageLookupValue =
          (IncorrectRepositoryReferencePackageLookupValue) packageLookupValue;
      assertThat(incorrectPackageLookupValue.getInvalidPackageIdentifier())
          .isEqualTo(packageIdentifier);
      assertThat(incorrectPackageLookupValue.getCorrectedPackageIdentifier().toString())
          .isEqualTo(expectedCorrectedPackageIdentifier);
    }

    @Test
    public void testCorrectPackageDetection_absolutePath() throws Exception {
      scratch.overwriteFile(
          "WORKSPACE",
          "local_repository(name='local', path=__workspace_dir__ + '/" + repositoryPath + "')");
      scratch.file(PathFragment.create(repositoryPath).getRelative("WORKSPACE").getPathString());
      scratch.file(
          PathFragment.create(repositoryPath)
              .getRelative(packagePath)
              .getRelative("BUILD")
              .getPathString());

      PackageIdentifier packageIdentifier =
          PackageIdentifier.createInMainRepo(
              PathFragment.create(repositoryPath).getRelative(packagePath));
      PackageLookupValue packageLookupValue = lookupPackage(packageIdentifier);
      assertThat(packageLookupValue.packageExists()).isFalse();
      assertThat(packageLookupValue)
          .isInstanceOf(IncorrectRepositoryReferencePackageLookupValue.class);

      IncorrectRepositoryReferencePackageLookupValue incorrectPackageLookupValue =
          (IncorrectRepositoryReferencePackageLookupValue) packageLookupValue;
      assertThat(incorrectPackageLookupValue.getInvalidPackageIdentifier())
          .isEqualTo(packageIdentifier);
      assertThat(incorrectPackageLookupValue.getCorrectedPackageIdentifier().toString())
          .isEqualTo(expectedCorrectedPackageIdentifier);
    }
  }

  @Test
  // TODO b/331316530: Temporarily removed to avoid build memory regressions. Re-enable as opt in.
  @Ignore
  public void testInvalidProjectFile() throws Exception {
    scratch.file("mypackage/BUILD");
    scratch.dir("mypackage/PROJECT.scl");
    PackageLookupValue packageLookupValue = lookupPackage("mypackage");
    assertThat(packageLookupValue.packageExists()).isFalse();
    assertThat(packageLookupValue.getErrorReason()).isEqualTo(ErrorReason.INVALID_PROJECT_FILE);
    assertThat(packageLookupValue.getErrorMsg()).isNotNull();
  }
}
