// Copyright 2017 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.repository;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.auto.value.AutoValue;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.actions.ThreadStateReceiver;
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.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.TargetPattern;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.packages.BuildFileName;
import com.google.devtools.build.lib.packages.Rule;
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.RepositoryDelegatorFunction;
import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
import com.google.devtools.build.lib.skyframe.ExternalPackageFunction;
import com.google.devtools.build.lib.skyframe.FileFunction;
import com.google.devtools.build.lib.skyframe.FileStateFunction;
import com.google.devtools.build.lib.skyframe.LocalRepositoryLookupFunction;
import com.google.devtools.build.lib.skyframe.PackageFunction;
import com.google.devtools.build.lib.skyframe.PackageFunction.GlobbingStrategy;
import com.google.devtools.build.lib.skyframe.PackageLookupFunction;
import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy;
import com.google.devtools.build.lib.skyframe.PrecomputedValue;
import com.google.devtools.build.lib.skyframe.RegisteredExecutionPlatformsFunction;
import com.google.devtools.build.lib.skyframe.RegisteredToolchainsFunction;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.skyframe.WorkspaceFileFunction;
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.Root;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.lib.vfs.SyscallCache;
import com.google.devtools.build.skyframe.AbstractSkyKey;
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.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkSemantics;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link ExternalPackageHelper}. */
@RunWith(JUnit4.class)
public class ExternalPackageHelperTest extends BuildViewTestCase {
  private static final Root MOCK_ROOT = mockRoot();

  private static Root mockRoot() {
    Root root = mock(Root.class);
    when(root.isAbsolute()).thenReturn(false);
    return root;
  }

  private static final EvaluationContext EVALUATION_OPTIONS =
      EvaluationContext.newBuilder()
          .setKeepGoing(false)
          .setNumThreads(SkyframeExecutor.DEFAULT_THREAD_COUNT)
          .setEventHandler(NullEventHandler.INSTANCE)
          .build();

  private MemoizingEvaluator evaluator;

  @Before
  public void createEnvironment() {
    AnalysisMock analysisMock = AnalysisMock.get();
    AtomicReference<PathPackageLocator> pkgLocator =
        new AtomicReference<>(
            new PathPackageLocator(
                outputBase,
                ImmutableList.of(Root.fromPath(rootDirectory)),
                BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY));
    AtomicReference<ImmutableSet<PackageIdentifier>> 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.ERROR,
            BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY,
            BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));
    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));
    RuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider();
    skyFunctions.put(
        WorkspaceFileValue.WORKSPACE_FILE,
        new WorkspaceFileFunction(
            ruleClassProvider,
            analysisMock
                .getPackageFactoryBuilderForTesting(directories)
                .build(ruleClassProvider, fileSystem),
            directories,
            /*bzlLoadFunctionForInlining=*/ null));
    skyFunctions.put(
        SkyFunctions.PACKAGE,
        new PackageFunction(
            null,
            null,
            null,
            /*numPackagesSuccessfullyLoaded=*/ new AtomicInteger(),
            null,
            /*packageProgress=*/ null,
            PackageFunction.ActionOnIOExceptionReadingBuildFile.UseOriginalIOException.INSTANCE,
            GlobbingStrategy.SKYFRAME_HYBRID,
            k -> ThreadStateReceiver.NULL_INSTANCE));
    skyFunctions.put(
        SkyFunctions.EXTERNAL_PACKAGE,
        new ExternalPackageFunction(BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));
    skyFunctions.put(
        SkyFunctions.LOCAL_REPOSITORY_LOOKUP,
        new LocalRepositoryLookupFunction(BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER));

    // Helper Skyfunctions to call ExternalPackageUtil.
    skyFunctions.put(GET_RULE_BY_NAME_FUNCTION, new GetRuleByNameFunction());
    skyFunctions.put(
        GET_REGISTERED_EXECUTION_PLATFORMS_FUNCTION, new GetRegisteredExecutionPlatformsFunction());
    skyFunctions.put(GET_REGISTERED_TOOLCHAINS_FUNCTION, new GetRegisteredToolchainsFunction());

    RecordingDifferencer differencer = new SequencedRecordingDifferencer();
    evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer);
    PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
    PrecomputedValue.STARLARK_SEMANTICS.set(differencer, StarlarkSemantics.DEFAULT);
    RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE.set(
        differencer, Optional.empty());
    RepositoryDelegatorFunction.ENABLE_BZLMOD.set(differencer, false);
  }

  @Test
  public void getRuleByName() throws Exception {
    if (!analysisMock.isThisBazel()) {
      return;
    }
    scratch.overwriteFile("WORKSPACE", "local_repository(name = 'foo', path = 'path/to/repo')");

    SkyKey key = getRuleByNameKey("foo");
    EvaluationResult<GetRuleByNameValue> result = getRuleByName(key);

    assertThatEvaluationResult(result).hasNoError();

    Rule rule = result.get(key).rule();
    assertThat(rule).isNotNull();
    assertThat(rule.getName()).isEqualTo("foo");
  }

  private EvaluationResult<GetRuleByNameValue> getRuleByName(SkyKey key)
      throws InterruptedException {
    return evaluator.evaluate(ImmutableList.of(key), EVALUATION_OPTIONS);
  }

  @Test
  public void getRuleByName_missing() throws Exception {
    if (!analysisMock.isThisBazel()) {
      return;
    }
    scratch.overwriteFile("WORKSPACE", "local_repository(name = 'foo', path = 'path/to/repo')");

    SkyKey key = getRuleByNameKey("bar");
    EvaluationResult<GetRuleByNameValue> result = getRuleByName(key);

    assertThatEvaluationResult(result)
        .hasErrorEntryForKeyThat(key)
        .hasExceptionThat()
        .hasMessageThat()
        .contains("The rule named 'bar' could not be resolved");
  }

  @Test
  public void getRegisteredToolchains_addedInWorkspace() throws Exception {
    scratch.overwriteFile(
        "WORKSPACE", "register_toolchains(", "  '//toolchain:tc1',", "  '//toolchain:tc2')");

    assertThat(getRegisteredToolchains())
        // There are default toolchains that are always registered, so just check for the ones added
        .containsAtLeast("//toolchain:tc1", "//toolchain:tc2")
        .inOrder();
  }

  @Test
  public void getRegisteredToolchains_workspaceBazelPreferred() throws Exception {
    scratch.overwriteFile("WORKSPACE", "register_toolchains('//toolchain:WORKSPACE')");
    scratch.overwriteFile("WORKSPACE.bazel", "register_toolchains('//toolchain:WORKSPACE_bazel')");

    getRegisteredToolchains();
    ImmutableList<String> registeredToolchains = getRegisteredToolchains();

    assertThat(registeredToolchains).contains("//toolchain:WORKSPACE_bazel");
    assertThat(registeredToolchains).doesNotContain("//toolchain:WORKSPACE");
  }

  @Test
  public void getRegisteredToolchains_workspaceBazelNotAFile() throws Exception {
    scratch.overwriteFile("WORKSPACE", "register_toolchains('//toolchain:WORKSPACE')");
    scratch.dir("WORKSPACE.bazel");

    getRegisteredToolchains();
    ImmutableList<String> registeredToolchains = getRegisteredToolchains();

    assertThat(registeredToolchains).contains("//toolchain:WORKSPACE");
  }

  @Test
  public void findWorkspaceFile_firstIsFile() throws Exception {
    ExternalPackageHelper helper =
        new ExternalPackageHelper(
            ImmutableList.of(BuildFileName.WORKSPACE, BuildFileName.WORKSPACE_DOT_BAZEL));
    Environment env = createMockEnvironment();
    mockFileValue(env, BuildFileName.WORKSPACE, /*isFile=*/ true);

    assertThat(helper.findWorkspaceFile(env)).isEqualTo(rootedPath(BuildFileName.WORKSPACE));
  }

  @Test
  public void findWorkspaceFile_firstNotAFileFallbackToSecond() throws Exception {
    ExternalPackageHelper helper =
        new ExternalPackageHelper(
            ImmutableList.of(BuildFileName.WORKSPACE_DOT_BAZEL, BuildFileName.WORKSPACE));
    Environment env = createMockEnvironment();
    mockFileValue(env, BuildFileName.WORKSPACE_DOT_BAZEL, /*isFile=*/ false);
    mockFileValue(env, BuildFileName.WORKSPACE, /*isFile=*/ true);

    assertThat(helper.findWorkspaceFile(env)).isEqualTo(rootedPath(BuildFileName.WORKSPACE));
  }

  @Test
  public void findWorkspaceFile_noneAreFilesReturnLast() throws Exception {
    ExternalPackageHelper helper =
        new ExternalPackageHelper(
            ImmutableList.of(BuildFileName.WORKSPACE_DOT_BAZEL, BuildFileName.WORKSPACE));
    Environment env = createMockEnvironment();
    mockFileValue(env, BuildFileName.WORKSPACE_DOT_BAZEL, /*isFile=*/ false);
    mockFileValue(env, BuildFileName.WORKSPACE, /*isFile=*/ false);

    assertThat(helper.findWorkspaceFile(env)).isEqualTo(rootedPath(BuildFileName.WORKSPACE));
  }

  @Test
  public void getRegisteredExecutionPlatforms() throws Exception {
    scratch.overwriteFile(
        "WORKSPACE", "register_execution_platforms(", "  '//platform:ep1',", "  '//platform:ep2')");

    SkyKey key = () -> GET_REGISTERED_EXECUTION_PLATFORMS_FUNCTION;
    EvaluationResult<GetRegisteredExecutionPlatformsValue> result =
        getRegisteredExecutionPlatforms(key);

    assertThatEvaluationResult(result).hasNoError();

    assertThat(result.get(key).registeredExecutionPlatforms())
        .containsExactly("//platform:ep1", "//platform:ep2")
        .inOrder();
  }

  private EvaluationResult<GetRegisteredExecutionPlatformsValue> getRegisteredExecutionPlatforms(
      SkyKey key) throws InterruptedException {
    return evaluator.evaluate(ImmutableList.of(key), EVALUATION_OPTIONS);
  }

  // HELPER SKYFUNCTIONS

  private static Environment createMockEnvironment() throws InterruptedException {
    Environment env = mock(Environment.class);
    when(env.getValue(PrecomputedValue.PATH_PACKAGE_LOCATOR.getKeyForTesting()))
        .thenReturn(
            new PrecomputedValue(
                new PathPackageLocator(
                    mock(Path.class), ImmutableList.of(MOCK_ROOT), ImmutableList.of())));
    return env;
  }

  private static void mockFileValue(Environment env, BuildFileName buildFileName, boolean isFile)
      throws InterruptedException {
    FileValue fileValue = mock(FileValue.class);
    when(fileValue.isFile()).thenReturn(isFile);
    when(env.getValue(FileValue.key(rootedPath(buildFileName)))).thenReturn(fileValue);
  }

  private static RootedPath rootedPath(BuildFileName buildFileName) {
    return RootedPath.toRootedPath(MOCK_ROOT, buildFileName.getFilenameFragment());
  }

  private ImmutableList<String> getRegisteredToolchains() throws InterruptedException {
    SkyKey key = getRegisteredToolchainsKey();
    EvaluationResult<GetRegisteredToolchainsValue> result =
        evaluator.evaluate(ImmutableList.of(key), EVALUATION_OPTIONS);

    assertThatEvaluationResult(result).hasNoError();
    return result.get(key).registeredToolchains();
  }

  // GetRuleByName.
  private static SkyKey getRuleByNameKey(String ruleName) {
    return new Key(ruleName);
  }

  private static final SkyFunctionName GET_RULE_BY_NAME_FUNCTION =
      SkyFunctionName.createHermetic("GET_RULE_BY_NAME");

  @AutoValue
  abstract static class GetRuleByNameValue implements SkyValue {
    abstract Rule rule();

    static GetRuleByNameValue create(Rule rule) {
      return new AutoValue_ExternalPackageHelperTest_GetRuleByNameValue(rule);
    }
  }

  private static final class GetRuleByNameFunction implements SkyFunction {

    @Nullable
    @Override
    public SkyValue compute(SkyKey skyKey, Environment env)
        throws SkyFunctionException, InterruptedException {
      String ruleName = (String) skyKey.argument();

      Rule rule =
          BazelSkyframeExecutorConstants.EXTERNAL_PACKAGE_HELPER.getRuleByName(ruleName, env);
      if (rule == null) {
        return null;
      }
      return GetRuleByNameValue.create(rule);
    }
  }

  // GetRegisteredToolchains.
  private static SkyKey getRegisteredToolchainsKey() {
    return () -> GET_REGISTERED_TOOLCHAINS_FUNCTION;
  }

  private static final SkyFunctionName GET_REGISTERED_TOOLCHAINS_FUNCTION =
      SkyFunctionName.createHermetic("GET_REGISTERED_TOOLCHAINS");

  @AutoValue
  abstract static class GetRegisteredToolchainsValue implements SkyValue {
    abstract ImmutableList<String> registeredToolchains();

    static GetRegisteredToolchainsValue create(Iterable<String> registeredToolchains) {
      return new AutoValue_ExternalPackageHelperTest_GetRegisteredToolchainsValue(
          ImmutableList.copyOf(registeredToolchains));
    }
  }

  private static final class GetRegisteredToolchainsFunction implements SkyFunction {

    @Nullable
    @Override
    public SkyValue compute(SkyKey skyKey, Environment env)
        throws SkyFunctionException, InterruptedException {
      List<TargetPattern> registeredToolchains =
          RegisteredToolchainsFunction.getWorkspaceToolchains(env);
      if (registeredToolchains == null) {
        return null;
      }
      return GetRegisteredToolchainsValue.create(
          registeredToolchains.stream()
              .map(TargetPattern::getOriginalPattern)
              .collect(toImmutableList()));
    }
  }

  private static final SkyFunctionName GET_REGISTERED_EXECUTION_PLATFORMS_FUNCTION =
      SkyFunctionName.createHermetic("GET_REGISTERED_EXECUTION_PLATFORMS_FUNCTION");

  @AutoValue
  abstract static class GetRegisteredExecutionPlatformsValue implements SkyValue {
    abstract ImmutableList<String> registeredExecutionPlatforms();

    static GetRegisteredExecutionPlatformsValue create(
        Iterable<String> registeredExecutionPlatforms) {
      return new AutoValue_ExternalPackageHelperTest_GetRegisteredExecutionPlatformsValue(
          ImmutableList.copyOf(registeredExecutionPlatforms));
    }
  }

  private static final class GetRegisteredExecutionPlatformsFunction implements SkyFunction {

    @Nullable
    @Override
    public SkyValue compute(SkyKey skyKey, Environment env)
        throws SkyFunctionException, InterruptedException {
      List<TargetPattern> registeredExecutionPlatforms =
          RegisteredExecutionPlatformsFunction.getWorkspaceExecutionPlatforms(env);
      if (registeredExecutionPlatforms == null) {
        return null;
      }
      return GetRegisteredExecutionPlatformsValue.create(
          registeredExecutionPlatforms.stream()
              .map(TargetPattern::getOriginalPattern)
              .collect(toImmutableList()));
    }
  }

  static class Key extends AbstractSkyKey<String> {
    private Key(String arg) {
      super(arg);
    }

    @Override
    public SkyFunctionName functionName() {
      return GET_RULE_BY_NAME_FUNCTION;
    }
  }
}
