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

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ServerDirectories;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.EventCollector;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.packages.BuildFileName;
import com.google.devtools.build.lib.packages.StarlarkSemanticsOptions;
import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestPackageFactoryBuilderFactory;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
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.RootedPath;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import com.google.devtools.build.skyframe.BuildDriver;
import com.google.devtools.build.skyframe.EvaluationContext;
import com.google.devtools.build.skyframe.EvaluationResult;
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.common.options.Options;
import com.google.devtools.common.options.OptionsProvider;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;

/**
 * Abstract base class for testing an implementation of a {@link SkyFunction} for {@link
 * SkyFunctions#COLLECT_PACKAGES_UNDER_DIRECTORY}.
 */
public abstract class AbstractCollectPackagesUnderDirectoryTest {
  protected FileSystem fileSystem;
  protected Root root;
  protected Path workingDir;
  private Scratch scratch;
  protected BlazeDirectories directories;
  private EventCollector eventCollector;
  private Reporter reporter;
  protected ConfiguredRuleClassProvider ruleClassProvider;
  private BuildDriver buildDriver;

  @Before
  public void setUp() throws IOException {
    fileSystem = new InMemoryFileSystem();
    workingDir = fileSystem.getPath(getWorkspacePathString());
    workingDir.createDirectoryAndParents();
    root = Root.fromPath(workingDir);
    scratch = new Scratch(workingDir);
    directories =
        new BlazeDirectories(
            new ServerDirectories(
                fileSystem.getPath("/install"),
                fileSystem.getPath("/output"),
                fileSystem.getPath("/user_root")),
            workingDir,
            /*defaultSystemJavabase=*/ null,
            /*productName=*/ "DummyProductNameForUnitTests");
    eventCollector = new EventCollector();
    reporter = new Reporter(new EventBus());
    reporter.addHandler(eventCollector);
  }

  protected abstract String getWorkspacePathString();

  protected abstract List<BuildFileName> getBuildFileNamesByPriority();

  protected abstract ImmutableMap<SkyFunctionName, SkyFunction> getExtraSkyFunctions();

  protected abstract SkyframeExecutorFactory makeSkyframeExecutorFactory();

  @Test
  public void noPackageErrors() throws Exception {
    initBuildDriver();

    scratch.file("BUILD");
    scratch.dir("a1/b1/c1");
    scratch.file("a1/b1/c1/BUILD");
    scratch.dir("a1/b1/c2");
    scratch.dir("a1/b2/c1");
    scratch.dir("a1/b2/c2");
    scratch.dir("a2/b1/c1");
    scratch.file("a2/b1/c1/BUILD");
    scratch.dir("a2/b1/c2");
    scratch.dir("a2/b2/c1");
    scratch.dir("a2/b2/c2");
    scratch.file("a2/b2/c2/BUILD");

    {
      CollectPackagesUnderDirectoryValue collectPackagesUnderDirectoryValue =
          getCollectPackagesUnderDirectoryValue("");
      assertThat(collectPackagesUnderDirectoryValue.isDirectoryPackage()).isTrue();
      assertThat(
              collectPackagesUnderDirectoryValue
                  .getSubdirectoryTransitivelyContainsPackagesOrErrors())
          .containsExactly(
              rootedPath("tools"), Boolean.TRUE,
              rootedPath("a1"), Boolean.TRUE,
              rootedPath("a2"), Boolean.TRUE);
    }

    {
      CollectPackagesUnderDirectoryValue collectPackagesUnderDirectoryValue =
          getCollectPackagesUnderDirectoryValue("a1");
      assertThat(collectPackagesUnderDirectoryValue.isDirectoryPackage()).isFalse();
      assertThat(
              collectPackagesUnderDirectoryValue
                  .getSubdirectoryTransitivelyContainsPackagesOrErrors())
          .containsExactly(rootedPath("a1/b1"), Boolean.TRUE, rootedPath("a1/b2"), Boolean.FALSE);
    }

    {
      CollectPackagesUnderDirectoryValue collectPackagesUnderDirectoryValue =
          getCollectPackagesUnderDirectoryValue("a2/b1");
      assertThat(collectPackagesUnderDirectoryValue.isDirectoryPackage()).isFalse();
      assertThat(
              collectPackagesUnderDirectoryValue
                  .getSubdirectoryTransitivelyContainsPackagesOrErrors())
          .containsExactly(
              rootedPath("a2/b1/c1"), Boolean.TRUE, rootedPath("a2/b1/c2"), Boolean.FALSE);
    }
  }

  @Test
  public void packageErrors() throws Exception {
    initBuildDriver();

    scratch.dir("a1/b1");
    scratch.file("a1/b1/BUILD", "xxx");
    scratch.dir("a1/b2");
    scratch.dir("a2/b1");
    scratch.dir("a2/b2");
    scratch.file("a2/b2/BUILD", "yyy");

    CollectPackagesUnderDirectoryValue collectPackagesUnderDirectoryValue =
        getCollectPackagesUnderDirectoryValue("");
    assertThat(collectPackagesUnderDirectoryValue.isDirectoryPackage()).isFalse();
    assertThat(
            collectPackagesUnderDirectoryValue
                .getSubdirectoryTransitivelyContainsPackagesOrErrors())
        .containsExactly(
            rootedPath("tools"), Boolean.TRUE,
            rootedPath("a1"), Boolean.TRUE,
            rootedPath("a2"), Boolean.TRUE);
    MoreAsserts.assertContainsEvent(eventCollector, "Loading package: a1/b1");
    MoreAsserts.assertContainsEvent(eventCollector, "a1/b1/BUILD:1:1: name 'xxx' is not defined");
    MoreAsserts.assertContainsEvent(eventCollector, "Loading package: a2/b2");
    MoreAsserts.assertContainsEvent(eventCollector, "a2/b2/BUILD:1:1: name 'yyy' is not defined");
  }

  @Test
  public void symlinks() throws Exception {
    initBuildDriver();

    Path a1DirPath = scratch.dir("a1");
    scratch.dir("a1/b1/c1");
    Path a1CircularPath = scratch.resolve("a1/circular");
    FileSystemUtils.ensureSymbolicLink(a1CircularPath, a1CircularPath);
    scratch.file("a1/b1/c1/BUILD");
    FileSystemUtils.ensureSymbolicLink(scratch.resolve("a2"), a1DirPath);
    scratch.dir("a3");
    scratch.file(
        "a3/DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN");
    FileSystemUtils.ensureSymbolicLink(scratch.resolve("a3/dirlink"), a1DirPath);

    CollectPackagesUnderDirectoryValue collectPackagesUnderDirectoryValue =
        getCollectPackagesUnderDirectoryValue("");
    assertThat(collectPackagesUnderDirectoryValue.isDirectoryPackage()).isFalse();
    assertThat(
            collectPackagesUnderDirectoryValue
                .getSubdirectoryTransitivelyContainsPackagesOrErrors())
        .containsExactly(
            rootedPath("tools"), Boolean.TRUE,
            rootedPath("a1"), Boolean.TRUE,
            rootedPath("a2"), Boolean.TRUE,
            rootedPath("a3"), Boolean.FALSE);
    MoreAsserts.assertContainsEvent(eventCollector, "Loading package: a1/b1/c1");
    MoreAsserts.assertContainsEvent(eventCollector, "Loading package: a2/b1/c1");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a3/b1/c1");
    MoreAsserts.assertContainsEvent(
        eventCollector,
        "Failed to get information about path, for a1/circular, skipping: Symlink cycle");
    MoreAsserts.assertContainsEvent(
        eventCollector,
        "Failed to get information about path, for a2/circular, skipping: Symlink cycle");
  }

  @Test
  public void excludedPaths() throws Exception {
    initBuildDriver();

    scratch.dir("a1/b1/c1");
    scratch.file("a1/b1/c1/BUILD");
    scratch.dir("a1/b1/c2");
    scratch.file("a1/b1/c2/BUILD");
    scratch.dir("a1/b2/c1");
    scratch.file("a1/b2/c1/BUILD");
    scratch.dir("a1/b2/c2");
    scratch.file("a1/b2/c2/BUILD");
    scratch.dir("a2/b1/c1");
    scratch.file("a2/b1/c1/BUILD");
    scratch.dir("a2/b1/c2");
    scratch.file("a2/b1/c2/BUILD");
    scratch.dir("a2/b2/c1");
    scratch.file("a2/b2/c1/BUILD");
    scratch.dir("a2/b2/c2");
    scratch.file("a2/b2/c2/BUILD");

    CollectPackagesUnderDirectoryValue collectPackagesUnderDirectoryValue =
        getCollectPackagesUnderDirectoryValue(
            "",
            /*excludedPaths=*/ ImmutableSet.of(
                PathFragment.create("a1"),
                PathFragment.create("a2/b1"),
                PathFragment.create("a2/b2/c2")));
    assertThat(collectPackagesUnderDirectoryValue.isDirectoryPackage()).isFalse();
    // There is not supposed to be a map entry for excluded subdirectories.
    assertThat(
            collectPackagesUnderDirectoryValue
                .getSubdirectoryTransitivelyContainsPackagesOrErrors())
        .containsExactly(
            rootedPath("tools"), Boolean.TRUE,
            rootedPath("a2"), Boolean.TRUE);
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a1/b1/c1");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a1/b1/c2");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a1/b2/c1");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a1/b1/c2");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a2/b1/c1");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a2/b1/c2");
    MoreAsserts.assertContainsEvent(eventCollector, "Loading package: a2/b2/c1");
    MoreAsserts.assertDoesNotContainEvent(eventCollector, "Loading package: a2/b2/c2");
  }

  private void initBuildDriver() throws AbruptExitException, InterruptedException, IOException {
    PathPackageLocator pathPackageLocator =
        PathPackageLocator.createWithoutExistenceCheck(
            directories.getOutputBase(), ImmutableList.of(root), getBuildFileNamesByPriority());
    PackageCacheOptions packageCacheOptions = Options.getDefaults(PackageCacheOptions.class);
    packageCacheOptions.packagePath = ImmutableList.of(getWorkspacePathString());
    scratch.file("tools/BUILD");
    scratch.file("tools/empty_prelude.bzl");
    ruleClassProvider =
        new ConfiguredRuleClassProvider.Builder()
            .setRunfilesPrefix("workspace")
            .setPrelude("//tools:empty_prelude.bzl")
            .build();
    SkyframeExecutor skyframeExecutor =
        makeSkyframeExecutorFactory()
            .create(
                TestPackageFactoryBuilderFactory.getInstance()
                    .builder(directories)
                    .build(ruleClassProvider, fileSystem),
                fileSystem,
                directories,
                new ActionKeyContext(),
                /*workspaceStatusActionFactory=*/ null,
                /*diffAwarenessFactories=*/ ImmutableList.of(),
                getExtraSkyFunctions(),
                /*customDirtinessCheckers=*/ ImmutableList.of(),
                /*managedDirectoriesKnowledge=*/ null);
    skyframeExecutor.injectExtraPrecomputedValues(
        ImmutableList.of(
            PrecomputedValue.injected(
                RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE, Optional.absent()),
            PrecomputedValue.injected(
                RepositoryDelegatorFunction.REPOSITORY_OVERRIDES, ImmutableMap.of()),
            PrecomputedValue.injected(
                RepositoryDelegatorFunction.DEPENDENCY_FOR_UNCONDITIONAL_FETCHING,
                RepositoryDelegatorFunction.DONT_FETCH_UNCONDITIONALLY)));
    skyframeExecutor.sync(
        reporter,
        packageCacheOptions,
        pathPackageLocator,
        Options.getDefaults(StarlarkSemanticsOptions.class),
        UUID.randomUUID(),
        /*clientEnv=*/ ImmutableMap.of(),
        new TimestampGranularityMonitor(BlazeClock.instance()),
        OptionsProvider.EMPTY);
    buildDriver = skyframeExecutor.getDriver();
  }

  private CollectPackagesUnderDirectoryValue getCollectPackagesUnderDirectoryValue(String directory)
      throws InterruptedException {
    return getCollectPackagesUnderDirectoryValue(directory, /*excludedPaths=*/ ImmutableSet.of());
  }

  private CollectPackagesUnderDirectoryValue getCollectPackagesUnderDirectoryValue(
      String directory, ImmutableSet<PathFragment> excludedPaths) throws InterruptedException {
    SkyKey key =
        CollectPackagesUnderDirectoryValue.key(
            RepositoryName.MAIN, rootedPath(directory), excludedPaths);
    return evaluate(key).get(key);
  }

  private RootedPath rootedPath(String relativePath) {
    return RootedPath.toRootedPath(root, PathFragment.create(relativePath));
  }

  private EvaluationResult<CollectPackagesUnderDirectoryValue> evaluate(SkyKey key)
      throws InterruptedException {
    EvaluationContext evaluationContext =
        EvaluationContext.newBuilder()
            .setKeepGoing(true)
            .setNumThreads(1)
            .setEventHander(new Reporter(new EventBus(), reporter))
            .build();
    return buildDriver.evaluate(ImmutableList.of(key), evaluationContext);
  }
}
