// Copyright 2020 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.toolchains;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.analysis.testing.ToolchainCollectionSubject.assertThat;
import static com.google.devtools.build.lib.analysis.testing.ToolchainContextSubject.assertThat;
import static com.google.devtools.build.lib.skyframe.PrerequisiteProducer.getDependencyContext;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.analysis.AnalysisResult;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.ToolchainCollection;
import com.google.devtools.build.lib.analysis.ToolchainContext;
import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.analysis.constraints.IncompatibleTargetChecker.IncompatibleTargetException;
import com.google.devtools.build.lib.analysis.producers.DependencyContext;
import com.google.devtools.build.lib.analysis.producers.DependencyContextProducer;
import com.google.devtools.build.lib.analysis.producers.TransitiveDependencyState;
import com.google.devtools.build.lib.analysis.test.BaselineCoverageAction;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.ConfiguredValueCreationException;
import com.google.devtools.build.lib.skyframe.PrerequisiteProducer;
import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
import com.google.devtools.build.skyframe.EvaluationResult;
import com.google.devtools.build.skyframe.SkyFunction;
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 com.google.errorprone.annotations.CanIgnoreReturnValue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests {@link ConfiguredTargetFunction}'s logic for determining each target toolchain context.
 *
 * <p>This is essentially an integration test for the toolchain part of {@link
 * DependencyContextProducer}. These methods form the core logic that figures out what a target's
 * toolchain dependencies are.
 *
 * <p>{@link ConfiguredTargetFunction} is a complicated class that does a lot of things. This test
 * focuses purely on the task of toolchain resolution. So instead of evaluating full {@link
 * ConfiguredTargetFunction} instances, it evaluates a mock {@link SkyFunction} that just wraps the
 * {@link PrerequisiteProducer#getDependencyContext} part. This keeps focus tight and integration
 * dependencies narrow.
 *
 * <p>We can't just call {@link ToolchainContextProducer} directly because that method needs a
 * {@link SkyFunction.Environment} and Blaze's test infrastructure doesn't support direct access to
 * environments.
 */
@RunWith(JUnit4.class)
public final class ToolchainsForTargetsTest extends AnalysisTestCase {
  /** Returns a {@link SkyKey} for a given <Target, BuildConfigurationValue> pair. */
  private static Key key(
      TargetAndConfiguration targetAndConfiguration, ConfiguredTargetKey configuredTargetKey) {
    return new AutoValue_ToolchainsForTargetsTest_Key(targetAndConfiguration, configuredTargetKey);
  }

  /** Key class for {@link ComputeUnloadedToolchainContextsFunction}. */
  @AutoValue
  abstract static class Key implements SkyKey {
    abstract TargetAndConfiguration targetAndConfiguration();

    abstract ConfiguredTargetKey configuredTargetKey();

    @Override
    public SkyFunctionName functionName() {
      return ComputeUnloadedToolchainContextsFunction.SKYFUNCTION_NAME;
    }
  }

  /**
   * Returns a {@link ToolchainCollection< UnloadedToolchainContext >} as the result of {@link
   * PrerequisiteProducer#getDependencyContext}.
   */
  @AutoValue
  abstract static class Value implements SkyValue {
    abstract ToolchainCollection<UnloadedToolchainContext> getToolchainCollection();

    static Value create(ToolchainCollection<UnloadedToolchainContext> toolchainCollection) {
      return new AutoValue_ToolchainsForTargetsTest_Value(toolchainCollection);
    }
  }

  /**
   * A mock {@link SkyFunction} that just calls {@link PrerequisiteProducer#getDependencyContext}
   * and returns its results.
   */
  static class ComputeUnloadedToolchainContextsFunction implements SkyFunction {
    static final SkyFunctionName SKYFUNCTION_NAME =
        SkyFunctionName.createHermetic(
            "CONFIGURED_TARGET_FUNCTION_COMPUTE_UNLOADED_TOOLCHAIN_CONTEXTS");

    private final LateBoundStateProvider stateProvider;

    ComputeUnloadedToolchainContextsFunction(LateBoundStateProvider lateBoundStateProvider) {
      this.stateProvider = lateBoundStateProvider;
    }

    @Override
    public SkyValue compute(SkyKey skyKey, Environment env)
        throws ComputeUnloadedToolchainContextsException, InterruptedException {
      Key key = (Key) skyKey.argument();
      var state = env.getState(PrerequisiteProducer.State::new);
      state.targetAndConfiguration = key.targetAndConfiguration();
      NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
      DependencyContext result;
      try {
        result =
            getDependencyContext(
                state,
                key.configuredTargetKey().getExecutionPlatformLabel(),
                stateProvider.lateBoundRuleClassProvider(),
                TransitiveDependencyState.createForTesting(
                    transitiveRootCauses, /* transitivePackages= */ null),
                env);
      } catch (ToolchainException
          | ConfiguredValueCreationException
          | IncompatibleTargetException
          | DependencyEvaluationException e) {
        throw new ComputeUnloadedToolchainContextsException(e);
      }
      if (!transitiveRootCauses.isEmpty()) {
        throw new IllegalStateException("expected empty: " + transitiveRootCauses.build().toList());
      }
      if (result == null) {
        return null;
      }
      return Value.create(result.unloadedToolchainContexts());
    }

    private static class ComputeUnloadedToolchainContextsException extends SkyFunctionException {
      ComputeUnloadedToolchainContextsException(Exception cause) {
        super(cause, Transience.PERSISTENT); // We can generalize the transience if/when needed.
      }
    }
  }

  /**
   * Provides build state to {@link ComputeUnloadedToolchainContextsFunction}. This needs to be
   * late-bound (i.e. we can't just pass the contents directly) because of the way {@link
   * AnalysisTestCase} works: the {@link AnalysisMock} instance that instantiates the function gets
   * created before the rest of the build state. See {@link AnalysisTestCase#createMocks} for
   * details.
   */
  private class LateBoundStateProvider {
    RuleClassProvider lateBoundRuleClassProvider() {
      return ruleClassProvider;
    }
  }

  /**
   * An {@link AnalysisMock} that injects {@link ComputeUnloadedToolchainContextsFunction} into the
   * Skyframe executor.
   */
  private static final class AnalysisMockWithComputeDepsFunction extends AnalysisMock.Delegate {
    private final LateBoundStateProvider stateProvider;

    AnalysisMockWithComputeDepsFunction(AnalysisMock parent, LateBoundStateProvider stateProvider) {
      super(parent);
      this.stateProvider = stateProvider;
    }

    @Override
    public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(
        BlazeDirectories directories) {
      return ImmutableMap.<SkyFunctionName, SkyFunction>builder()
          .putAll(super.getSkyFunctions(directories))
          .put(
              ComputeUnloadedToolchainContextsFunction.SKYFUNCTION_NAME,
              new ComputeUnloadedToolchainContextsFunction(stateProvider))
          .buildOrThrow();
    }
  }

  @Override
  protected AnalysisMock getAnalysisMock() {
    return new AnalysisMockWithComputeDepsFunction(
        super.getAnalysisMock(), new LateBoundStateProvider());
  }

  public ToolchainCollection<UnloadedToolchainContext> getToolchainCollection(
      ConfiguredTarget configuredTarget, ConfiguredTargetKey configuredTargetKey)
      throws InterruptedException {
    String targetLabel = configuredTarget.getOriginalLabel().toString();
    SkyKey key =
        key(
            new TargetAndConfiguration(getTarget(targetLabel), getConfiguration(configuredTarget)),
            configuredTargetKey);
    // Analysis phase ended after the update() call in getToolchainCollection. We must re-enable
    // analysis so we can call ConfiguredTargetFunction again without raising an error.
    skyframeExecutor.getSkyframeBuildView().enableAnalysis(true);
    EvaluationResult<Value> evalResult =
        SkyframeExecutorTestUtils.evaluate(skyframeExecutor, key, /*keepGoing=*/ false, reporter);
    // Test call has finished, to reset the state.
    skyframeExecutor.getSkyframeBuildView().enableAnalysis(false);
    return evalResult.get(key).getToolchainCollection();
  }

  public ToolchainCollection<UnloadedToolchainContext> getToolchainCollection(String targetLabel)
      throws Exception {
    ConfiguredTarget target = Iterables.getOnlyElement(update(targetLabel).getTargetsToBuild());
    return getToolchainCollection(
        target,
        ConfiguredTargetKey.builder()
            .setLabel(target.getOriginalLabel())
            .setConfigurationKey(target.getConfigurationKey())
            .build());
  }

  @Before
  public void createToolchains() throws Exception {
    scratch.appendFile("WORKSPACE", "register_toolchains('//toolchains:all')");

    scratch.file(
        "toolchain/toolchain_def.bzl",
        "def _impl(ctx):",
        "  toolchain = platform_common.ToolchainInfo(",
        "      data = ctx.attr.data)",
        "  return [toolchain]",
        "test_toolchain = rule(",
        "    implementation = _impl,",
        "    attrs = {",
        "       'data': attr.string()})");

    scratch.file("toolchain/BUILD", "toolchain_type(name = 'test_toolchain')");

    scratch.appendFile(
        "toolchains/BUILD",
        "load('//toolchain:toolchain_def.bzl', 'test_toolchain')",
        "toolchain(",
        "    name = 'toolchain_1',",
        "    toolchain_type = '//toolchain:test_toolchain',",
        "    exec_compatible_with = [],",
        "    target_compatible_with = [],",
        "    toolchain = ':toolchain_1_impl')",
        "test_toolchain(",
        "  name='toolchain_1_impl',",
        "  data = 'foo')",
        "toolchain(",
        "    name = 'toolchain_2',",
        "    toolchain_type = '//toolchain:test_toolchain',",
        "    exec_compatible_with = [],",
        "    target_compatible_with = [],",
        "    toolchain = ':toolchain_2_impl')",
        "test_toolchain(",
        "    name='toolchain_2_impl',",
        "    data = 'bar')");

    scratch.appendFile(
        "toolchain/rule.bzl",
        "def _impl(ctx):",
        "    data = ctx.toolchains['//toolchain:test_toolchain'].data",
        "    return []",
        "my_rule = rule(",
        "    implementation = _impl,",
        "    toolchains = ['//toolchain:test_toolchain'],",
        ")");
  }

  // actual tests
  @Test
  public void basicToolchains() throws Exception {
    scratch.file("a/BUILD", "load('//toolchain:rule.bzl', 'my_rule')", "my_rule(name = 'a')");

    ToolchainCollection<UnloadedToolchainContext> toolchainCollection =
        getToolchainCollection("//a");
    assertThat(toolchainCollection).isNotNull();
    assertThat(toolchainCollection).hasDefaultExecGroup();
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        .hasToolchainType("//toolchain:test_toolchain");
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        .hasResolvedToolchain("//toolchains:toolchain_1_impl");
  }

  @Test
  public void execPlatform() throws Exception {
    // Add some platforms and custom constraints.
    scratch.file("platforms/BUILD", "platform(name = 'local_platform_a')");

    // Test normal resolution, and with a per-target exec constraint.
    scratch.file("a/BUILD", "load('//toolchain:rule.bzl', 'my_rule')", "my_rule(name = 'a')");

    useConfiguration("--extra_execution_platforms=//platforms:local_platform_a");

    ToolchainCollection<UnloadedToolchainContext> toolchainCollection =
        getToolchainCollection("//a");
    assertThat(toolchainCollection).isNotNull();
    assertThat(toolchainCollection).hasDefaultExecGroup();
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        // First execution platform will be used.
        .hasExecutionPlatform("//platforms:local_platform_a");
  }

  @Test
  public void execPlatform_withExecConstraint() throws Exception {
    // Add some platforms and custom constraints.
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");

    // Test normal resolution, and with a per-target exec constraint.
    scratch.file(
        "a/BUILD",
        "load('//toolchain:rule.bzl', 'my_rule')",
        "my_rule(name = 'a',",
        "    exec_compatible_with = ['//platforms:local_value_b'],",
        ")");

    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b");

    ToolchainCollection<UnloadedToolchainContext> toolchainCollection =
        getToolchainCollection("//a");
    assertThat(toolchainCollection).isNotNull();
    assertThat(toolchainCollection).hasDefaultExecGroup();
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        // Exec constraint forces the use of this exec platform.
        .hasExecutionPlatform("//platforms:local_platform_b");
  }

  @Test
  public void execGroups_named() throws Exception {
    // Write a rule with exec groups.
    scratch.appendFile(
        "toolchain/exec_group_rule.bzl",
        "def _impl(ctx):",
        "    pass",
        "my_exec_group_rule = rule(",
        "    implementation = _impl,",
        "    exec_groups = {",
        "        'temp': exec_group(",
        "             toolchains = ['//toolchain:test_toolchain'],",
        "         ),",
        "    },",
        ")");

    scratch.file(
        "a/BUILD",
        "load('//toolchain:exec_group_rule.bzl', 'my_exec_group_rule')",
        "my_exec_group_rule(name = 'a')");

    ToolchainCollection<UnloadedToolchainContext> toolchainCollection =
        getToolchainCollection("//a");
    assertThat(toolchainCollection).isNotNull();
    assertThat(toolchainCollection).hasDefaultExecGroup();
    assertThat(toolchainCollection).defaultToolchainContext().toolchainTypes().isEmpty();
    assertThat(toolchainCollection).defaultToolchainContext().resolvedToolchainLabels().isEmpty();

    assertThat(toolchainCollection).hasExecGroup("temp");
    assertThat(toolchainCollection)
        .execGroup("temp")
        .hasToolchainType("//toolchain:test_toolchain");
    assertThat(toolchainCollection)
        .execGroup("temp")
        .hasResolvedToolchain("//toolchains:toolchain_1_impl");
    assertThat(toolchainCollection)
        .execGroup("temp")
        .hasToolchainType("//toolchain:test_toolchain");
    assertThat(toolchainCollection)
        .execGroup("temp")
        .hasResolvedToolchain("//toolchains:toolchain_1_impl");
  }

  @Test
  public void execGroups_defaultAndNamed() throws Exception {
    // Add another toolchain type.
    scratch.appendFile(
        "extra/BUILD",
        "load('//toolchain:toolchain_def.bzl', 'test_toolchain')",
        "toolchain_type(name = 'extra_toolchain')",
        "toolchain(",
        "    name = 'toolchain',",
        "    toolchain_type = ':extra_toolchain',",
        "    exec_compatible_with = [],",
        "    target_compatible_with = [],",
        "    toolchain = ':toolchain_impl')",
        "test_toolchain(",
        "    name='toolchain_impl',",
        "    data = 'foo')");

    // Write a rule with exec groups.
    scratch.appendFile(
        "toolchain/exec_group_rule.bzl",
        "def _impl(ctx):",
        "    pass",
        "my_exec_group_rule = rule(",
        "    implementation = _impl,",
        "    toolchains = ['//extra:extra_toolchain'],",
        "    exec_groups = {",
        "        'temp': exec_group(",
        "             toolchains = ['//toolchain:test_toolchain'],",
        "         ),",
        "    },",
        ")");

    scratch.file(
        "a/BUILD",
        "load('//toolchain:exec_group_rule.bzl', 'my_exec_group_rule')",
        "my_exec_group_rule(name = 'a')");

    useConfiguration("--extra_toolchains=//extra:toolchain");
    ToolchainCollection<UnloadedToolchainContext> toolchainCollection =
        getToolchainCollection("//a");
    assertThat(toolchainCollection).isNotNull();
    assertThat(toolchainCollection).hasDefaultExecGroup();
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        .hasToolchainType("//extra:extra_toolchain");
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        .hasResolvedToolchain("//extra:toolchain_impl");

    assertThat(toolchainCollection).hasExecGroup("temp");
    assertThat(toolchainCollection)
        .execGroup("temp")
        .hasToolchainType("//toolchain:test_toolchain");
    assertThat(toolchainCollection)
        .execGroup("temp")
        .hasResolvedToolchain("//toolchains:toolchain_1_impl");
  }

  @Test
  public void keepParentToolchainContext() throws Exception {
    // Add some platforms and custom constraints.
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");

    // Test normal resolution, and with a per-target exec constraint.
    scratch.file("a/BUILD", "load('//toolchain:rule.bzl', 'my_rule')", "my_rule(name = 'a')");

    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b");

    ConfiguredTarget target = Iterables.getOnlyElement(update("//a").getTargetsToBuild());
    ToolchainCollection<UnloadedToolchainContext> toolchainCollection =
        getToolchainCollection(
            target,
            ConfiguredTargetKey.builder()
                .setLabel(target.getOriginalLabel())
                .setConfigurationKey(target.getConfigurationKey())
                .setExecutionPlatformLabel(
                    Label.parseCanonicalUnchecked("//platforms:local_platform_b"))
                .build());

    assertThat(toolchainCollection).isNotNull();
    assertThat(toolchainCollection).hasDefaultExecGroup();

    // This should have the same exec platform as parentToolchainKey, which is local_platform_b.
    assertThat(toolchainCollection)
        .defaultToolchainContext()
        .hasExecutionPlatform("//platforms:local_platform_b");
  }

  /** Regression test for b/214105142, https://github.com/bazelbuild/bazel/issues/14521 */
  @Test
  public void toolchainWithDifferentExecutionPlatforms_doesNotGenerateConflictingCoverageAction()
      throws Exception {
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a', constraint_values = [':local_value_a'])",
        "platform(name = 'local_platform_b', constraint_values = [':local_value_b'])");
    scratch.file(
        "a/BUILD",
        "load('//toolchain:rule.bzl', 'my_rule')",
        "my_rule(name='a', exec_compatible_with=['//platforms:local_value_a'])",
        "my_rule(name='b', exec_compatible_with=['//platforms:local_value_b'])");
    useConfiguration(
        "--collect_code_coverage",
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b");

    update("//a:a", "//a:b");

    // Sanity check that a coverage action was generated for the rule itself.
    assertHasBaselineCoverageAction("//a:a", "Writing file a/a/baseline_coverage.dat");
    assertHasBaselineCoverageAction("//a:b", "Writing file a/b/baseline_coverage.dat");
    assertThat(getActions("//toolchains:toolchain_1_impl")).isEmpty();
    ToolchainContext toolchainAContext =
        getToolchainCollection("//a:a").getDefaultToolchainContext();
    assertThat(toolchainAContext).hasExecutionPlatform("//platforms:local_platform_a");
    assertThat(toolchainAContext).hasToolchainType("//toolchain:test_toolchain");
    assertThat(toolchainAContext).hasResolvedToolchain("//toolchains:toolchain_1_impl");
    ToolchainContext toolchainBContext =
        getToolchainCollection("//a:b").getDefaultToolchainContext();
    assertThat(toolchainBContext).hasExecutionPlatform("//platforms:local_platform_b");
    assertThat(toolchainBContext).hasToolchainType("//toolchain:test_toolchain");
    assertThat(toolchainBContext).hasResolvedToolchain("//toolchains:toolchain_1_impl");
  }

  @CanIgnoreReturnValue
  private AnalysisResult updateExplicitTarget(String label) throws Exception {
    return update(
        new EventBus(),
        defaultFlags().with(Flag.KEEP_GOING),
        /* explicitTargetPatterns= */ ImmutableSet.of(Label.parseCanonicalUnchecked(label)),
        /* aspects= */ ImmutableList.of(),
        /* aspectsParameters= */ ImmutableMap.of(),
        label);
  }

  @Test
  public void targetCompatibleWith_matchesExecCompatibleWith() throws Exception {
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");
    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b");
    scratch.file(
        "foo/BUILD",
        "sh_binary(name = 'tool', srcs = ['a.sh'], ",
        "  target_compatible_with = ['//platforms:local_value_b'])",
        "genrule(name = 'runtool', tools = [':tool'], cmd = '', outs = ['b.txt'],",
        "  exec_compatible_with = ['//platforms:local_value_b'])");

    AnalysisResult result = updateExplicitTarget("//foo:runtool");

    assertThat(result.hasError()).isFalse();
    assertNoEvents();
  }

  @Test
  public void targetCompatibleWith_mismatchesExecCompatibleWith() throws Exception {
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");
    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b");
    scratch.file(
        "foo/BUILD",
        "sh_binary(name = 'tool', srcs = ['a.sh'], ",
        "  target_compatible_with = ['//platforms:local_value_a'])",
        "genrule(name = 'runtool', tools = [':tool'], cmd = '', outs = ['b.txt'],",
        "  exec_compatible_with = ['//platforms:local_value_b'])");

    reporter.removeHandler(failFastHandler);
    AnalysisResult result = updateExplicitTarget("//foo:runtool");

    assertThat(result.hasError()).isTrue();
    assertContainsEvent(
        "Target //foo:runtool is incompatible and cannot be built, but was explicitly requested");
  }

  @Test
  public void targetCompatibleWith_mismatchesExecCompatibleInDifferentPackage() throws Exception {
    // Regression test for a case where incompatibility happens in an aspect tool in a different
    // package over a Starlark target with
    // --incompatible_visibility_private_attributes_at_definition
    // The tool is replaced with a fake target {@link
    // IncommpatibleTargetChecker#createIncompatibleRuleConfiguredTarget)
    // and it's verified if the tool is visible to the Starlark target.
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");

    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b",
        "--incompatible_visibility_private_attributes_at_definition");
    scratch.file(
        "foo/lib.bzl",
        "def _impl(ctx):",
        "  pass",
        "my_rule = rule(",
        "  _impl,",
        "  attrs = { '_my_tool': attr.label(default = '//tool') },",
        ")");
    scratch.file(
        "tool/BUILD",
        "sh_binary(name = 'tool', srcs = ['a.cc'], ",
        "  target_compatible_with = ['//platforms:local_value_a'])");
    scratch.file(
        "foo/BUILD", //
        "load(':lib.bzl','my_rule')",
        "my_rule(name = 'target_in_different_package')");

    reporter.removeHandler(failFastHandler);
    AnalysisResult result = updateExplicitTarget("//foo:target_in_different_package");

    assertThat(result.hasError()).isTrue();
    assertContainsEvent(
        "Target //foo:target_in_different_package is incompatible and cannot be built, but was"
            + " explicitly requested");
  }

  @Test
  public void targetCompatibleWith_mismatchesExecCompatibleDepInDifferentPackage()
      throws Exception {
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");

    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b",
        "--incompatible_visibility_private_attributes_at_definition");
    scratch.file(
        "foo/lib.bzl",
        "def _impl(ctx):",
        "  pass",
        "my_rule = rule(",
        "  _impl,",
        "  attrs = { '_my_tool': attr.label(default = '//tool') },",
        ")");
    scratch.file(
        "tool/BUILD",
        "sh_binary(name = 'tool', srcs = ['a.cc'], ",
        "  target_compatible_with = ['//platforms:local_value_a'])");
    scratch.file(
        "foo/BUILD",
        "load(':lib.bzl','my_rule')",
        "my_rule(name = 'dep')",
        "filegroup(name = 'target_with_dep', srcs = [':dep'])");

    reporter.removeHandler(failFastHandler);
    AnalysisResult result = updateExplicitTarget("//foo:target_with_dep");

    assertThat(result.hasError()).isTrue();
    assertContainsEvent(
        "Target //foo:target_with_dep is incompatible and cannot be built, but was"
            + " explicitly requested");
  }

  @Test
  public void targetCompatibleWith_mismatchesExecCompatibleWithinAspect() throws Exception {
    // Regression test for a case where incompatibility happens in an aspect tool in a different
    // package over a Starlark target with
    // --incompatible_visibility_private_attributes_at_definition
    // The tool is replaced with a fake target {@link
    // IncommpatibleTargetChecker#createIncompatibleRuleConfiguredTarget)
    // and it's verified if the tool is visible to the Starlark target the aspect is over.
    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'local_setting')",
        "constraint_value(name = 'local_value_a', constraint_setting = ':local_setting')",
        "constraint_value(name = 'local_value_b', constraint_setting = ':local_setting')",
        "platform(name = 'local_platform_a',",
        "    constraint_values = [':local_value_a'],",
        ")",
        "platform(name = 'local_platform_b',",
        "    constraint_values = [':local_value_b'],",
        ")");

    useConfiguration(
        "--extra_execution_platforms=//platforms:local_platform_a,//platforms:local_platform_b",
        "--incompatible_visibility_private_attributes_at_definition");
    scratch.file(
        "foo/lib.bzl",
        "def _impl_aspect(ctx, target):",
        "  return []",
        "my_aspect = aspect(",
        "  _impl_aspect,",
        "  attrs = { '_my_tool': attr.label(default = '//tool') },",
        "  exec_compatible_with = ['//platforms:local_value_a'],",
        ")",
        "def _impl(ctx):",
        "  pass",
        "my_rule = rule(",
        "  _impl,",
        "  attrs = { 'deps': attr.label_list(aspects = [my_aspect]) },",
        ")",
        "simple_starlark_rule = rule(",
        "  _impl,",
        ")");
    scratch.file(
        "tool/BUILD",
        "sh_binary(name = 'tool', srcs = ['a.cc'], ",
        "  target_compatible_with = ['//platforms:local_value_b'])");
    scratch.file(
        "foo/BUILD",
        "load(':lib.bzl','my_rule', 'simple_starlark_rule')",
        "simple_starlark_rule(name = 'simple_dep')",
        "my_rule(name = 'target_with_aspect', deps = [':simple_dep'])");

    reporter.removeHandler(failFastHandler);
    AnalysisResult result = updateExplicitTarget("//foo:target_with_aspect");

    // TODO(bazel-team): This should report an error similarly to {@code
    // #targetCompatibleWith_mismatchesExecCompatibleDepInDifferentPackage}
    assertThat(result.hasError()).isFalse();
  }

  private void assertHasBaselineCoverageAction(String label, String progressMessage)
      throws InterruptedException {
    Action coverageAction = Iterables.getOnlyElement(getActions(label));
    assertThat(coverageAction).isInstanceOf(BaselineCoverageAction.class);
    assertThat(coverageAction.getProgressMessage()).isEqualTo(progressMessage);
  }

  private ImmutableList<Action> getActions(String label) throws InterruptedException {
    return ((RuleConfiguredTarget) getConfiguredTarget(label))
        .getActions().stream().map(Action.class::cast).collect(toImmutableList());
  }
}
