// 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.analysis.constraints;

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

import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.testutil.UnknownRuleConfiguredTarget;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for the constraint enforcement system. */
@RunWith(JUnit4.class)
public class ConstraintsTest extends AbstractConstraintsTest {

  @Before
  public final void createBuildFile() throws Exception {
    // Support files for RuleClassWithImplicitAndLateBoundDefaults:
    scratch.file(
        "helpers/BUILD",
        """
        sh_library(name = 'implicit', srcs = ['implicit.sh'])
        sh_library(name = 'latebound', srcs = ['latebound.sh'])
        sh_library(name = 'default', srcs = ['default.sh'])
        """);
    scratch.file(
        "config/BUILD",
        """
        config_setting(name = 'a', values = {'define': 'mode=a'})
        config_setting(name = 'b', values = {'define': 'mode=b'})
        """);
  }

  /**
   * Dummy rule class for testing rule class defaults. This class applies valid defaults. Note
   * that the specified environments must be independently created.
   */
  private static final class RuleClassDefaultRule implements RuleDefinition {
    @Override
    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
      return builder
          .setUndocumented()
          .compatibleWith(Label.parseCanonicalUnchecked("//buildenv/rule_class_compat:b"))
          .restrictedTo(Label.parseCanonicalUnchecked("//buildenv/rule_class_restrict:d"))
          .build();
    }

    @Override
    public Metadata getMetadata() {
      return RuleDefinition.Metadata.builder()
          .name("rule_class_default")
          .ancestors(BaseRuleClasses.NativeActionCreatingRule.class)
          .factoryClass(UnknownRuleConfiguredTarget.class)
          .build();
    }
  }

  /**
   * Dummy rule class for testing rule class defaults. This class applies invalid defaults. Note
   * that the specified environments must be independently created.
   */
  private static final MockRule BAD_RULE_CLASS_DEFAULT_RULE =
      () ->
          MockRule.define(
              "bad_rule_class_default",
              (builder, env) ->
                  builder
                      .setUndocumented()
                      // These defaults are invalid since compatibleWith and restrictedTo can't mix
                      // environments from the same group.
                      .compatibleWith(
                          Label.parseCanonicalUnchecked("//buildenv/rule_class_compat:a"))
                      .restrictedTo(
                          Label.parseCanonicalUnchecked("//buildenv/rule_class_compat:b")));

  private static final MockRule RULE_WITH_IMPLICIT_AND_LATEBOUND_DEFAULTS =
      () ->
          MockRule.define(
              "rule_with_implicit_and_latebound_deps",
              (builder, env) ->
                  builder
                      .setUndocumented()
                      .add(
                          Attribute.attr("$implicit", BuildType.LABEL)
                              .value(Label.parseCanonicalUnchecked("//helpers:implicit")))
                      .add(
                          Attribute.attr(":latebound", BuildType.LABEL)
                              .value(
                                  Attribute.LateBoundDefault.fromConstantForTesting(
                                      Label.parseCanonicalUnchecked("//helpers:latebound"))))
                      .add(
                          Attribute.attr("normal", BuildType.LABEL)
                              .allowedFileTypes(FileTypeSet.NO_FILE)
                              .value(Label.parseCanonicalUnchecked("//helpers:default"))));

  private static final MockRule RULE_WITH_ENFORCED_IMPLICIT_ATTRIBUTE =
      () ->
          MockRule.define(
              "rule_with_enforced_implicit_deps",
              (builder, env) ->
                  builder
                      .setUndocumented()
                      .add(
                          Attribute.attr("$implicit", BuildType.LABEL)
                              .value(Label.parseCanonicalUnchecked("//helpers:implicit"))
                              .checkConstraints()));

  private static final MockRule RULE_WITH_SKIPPED_ATTRIBUTE = () -> MockRule.define(
      "rule_with_skipped_attr",
      (builder, env) ->
          builder
              .setUndocumented()
              .add(Attribute.attr("some_attr", BuildType.LABEL)
                  .allowedFileTypes(FileTypeSet.NO_FILE)
                  .dontCheckConstraints()));


  private static final MockRule CONSTRAINT_EXEMPT_RULE_CLASS = () -> MockRule.define(
      "totally_free_rule",
      (builder, env) ->
          builder
              .setUndocumented()
              .exemptFromConstraintChecking(
                  "for testing removal of restricted_to / compatible_with"));

  /** Injects the rule class default rules into the default test rule class provider. */
  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addRuleDefinition(new RuleClassDefaultRule());
    builder.addRuleDefinition(BAD_RULE_CLASS_DEFAULT_RULE);
    builder.addRuleDefinition(RULE_WITH_IMPLICIT_AND_LATEBOUND_DEFAULTS);
    builder.addRuleDefinition(RULE_WITH_ENFORCED_IMPLICIT_ATTRIBUTE);
    builder.addRuleDefinition(RULE_WITH_SKIPPED_ATTRIBUTE);
    builder.addRuleDefinition(CONSTRAINT_EXEMPT_RULE_CLASS);
    return builder.build();
  }

  /**
   * Writes the environments and environment groups referred to by the rule class defaults.
   */
  private void writeRuleClassDefaultEnvironments() throws Exception {
    new EnvironmentGroupMaker("buildenv/rule_class_compat").setEnvironments("a", "b")
        .setDefaults("a").make();
    new EnvironmentGroupMaker("buildenv/rule_class_restrict").setEnvironments("c", "d")
        .setDefaults("c").make();
  }

  @Test
  public void packageErrorOnEnvironmentGroupWithMissingEnvironments() throws Exception {
    scratch.file(
        "buildenv/envs/BUILD",
        """
        environment(name = 'env1')
        environment(name = 'env2')
        environment_group(
            name = 'envs',
            environments = [':env1', ':en2'],
            defaults = [':env1'])
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(scratchConfiguredTarget("foo", "g",
        "genrule("
            + "    name = 'g',"
            + "    srcs = [],"
            + "    outs = ['g.out'],"
            + "    cmd = '',"
            + "    restricted_to = ['//buildenv/envs:env1'])"))
        .isNull();
    assertContainsEvent("environment //buildenv/envs:en2 does not exist");
  }

  /**
   * By default, a rule *implicitly* supports all defaults, meaning the explicitly known
   * environment set is empty.
   */
  @Test
  public void defaultSupportedEnvironments() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    String ruleDef = getDependencyRule();
    assertThat(supportedEnvironments("dep", ruleDef)).isEmpty();
  }

  /**
   * "Constraining" a rule's environments explicitly sets them.
   */
  @Test
  public void constrainedSupportedEnvironments() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    String ruleDef = getDependencyRule(constrainedTo("//buildenv/foo:c"));
    assertThat(supportedEnvironments("dep", ruleDef))
        .containsExactlyElementsIn(asLabelSet("//buildenv/foo:c"));
  }

  /**
   * Specifying compatibility adds the specified environments to the defaults.
   */
  @Test
  public void compatibleSupportedEnvironments() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    String ruleDef = getDependencyRule(compatibleWith("//buildenv/foo:c"));
    assertThat(supportedEnvironments("dep", ruleDef))
        .containsExactlyElementsIn(asLabelSet("//buildenv/foo:a", "//buildenv/foo:c"));
  }

  /**
   * A rule can't support *no* environments.
   */
  @Test
  public void supportedEnvironmentsConstrainedtoNothing() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    reporter.removeHandler(failFastHandler);
    String ruleDef = getDependencyRule(constrainedTo());
    assertThat(scratchConfiguredTarget("hello", "dep", ruleDef)).isNull();
    assertContainsEvent("attribute cannot be empty");
  }

  /**
   * Restrict the environments within one group, declare compatibility for another.
   */
  @Test
  public void supportedEnvironmentsInMultipleGroups() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    new EnvironmentGroupMaker("buildenv/bar").setEnvironments("c", "d").setDefaults("c").make();
    String ruleDef = getDependencyRule(
        constrainedTo("//buildenv/foo:b"), compatibleWith("//buildenv/bar:d"));
    assertThat(supportedEnvironments("dep", ruleDef))
        .containsExactlyElementsIn(
            asLabelSet("//buildenv/foo:b", "//buildenv/bar:c", "//buildenv/bar:d"));
  }

  /**
   * The same label can't appear in both a constraint and a compatibility declaration.
   */
  @Test
  public void sameEnvironmentCompatibleAndRestricted() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    reporter.removeHandler(failFastHandler);
    String ruleDef = getDependencyRule(
        constrainedTo("//buildenv/foo:b"), compatibleWith("//buildenv/foo:b"));
    assertThat(scratchConfiguredTarget("hello", "dep", ruleDef)).isNull();
    assertContainsEvent("//buildenv/foo:b cannot appear both here and in restricted_to");
  }

  /**
   * Two labels from the same group can't appear in different attributes.
   */
  @Test
  public void sameGroupCompatibleAndRestricted() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    reporter.removeHandler(failFastHandler);
    String ruleDef = getDependencyRule(
        constrainedTo("//buildenv/foo:a"), compatibleWith("//buildenv/foo:b"));
    assertThat(scratchConfiguredTarget("hello", "dep", ruleDef)).isNull();
    assertContainsEvent(
        "//buildenv/foo:b and //buildenv/foo:a belong to the same environment group");
  }

  /**
   * Tests that rule class defaults change a rule's default set of environments.
   */
  @Test
  public void supportedEnvironmentsRuleClassDefaults() throws Exception {
    writeRuleClassDefaultEnvironments();
    String ruleDef = "rule_class_default(name = 'a')";
    Set<Label> expectedEnvironments = asLabelSet("//buildenv/rule_class_compat:a",
        "//buildenv/rule_class_compat:b", "//buildenv/rule_class_restrict:d");
    assertThat(supportedEnvironments("a", ruleDef)).containsExactlyElementsIn(expectedEnvironments);
  }

  /**
   * Tests that explicit declarations override rule class defaults.
   */
  @Test
  public void explicitAttributesOverrideRuleClassDefaults() throws Exception {
    writeRuleClassDefaultEnvironments();
    String ruleDef = "rule_class_default("
        + "    name = 'a',"
        + "    compatible_with = ['//buildenv/rule_class_restrict:c'],"
        + "    restricted_to = ['//buildenv/rule_class_compat:a'],"
        + ")";
    Set<Label> expectedEnvironments = asLabelSet("//buildenv/rule_class_compat:a",
        "//buildenv/rule_class_restrict:c", "//buildenv/rule_class_restrict:d");
    assertThat(supportedEnvironments("a", ruleDef)).containsExactlyElementsIn(expectedEnvironments);
  }

  /**
   * Tests that a rule's "known" supported environments includes those from groups referenced
   * in rule class defaults but not in explicit rule attributes.
   */
  @Test
  public void knownEnvironmentsIncludesThoseFromRuleClassDefaults() throws Exception {
    writeRuleClassDefaultEnvironments();
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    String ruleDef = "rule_class_default("
        + "    name = 'a',"
        + "    restricted_to = ['//buildenv/foo:b'],"
        + ")";
    Set<Label> expectedEnvironments = asLabelSet("//buildenv/rule_class_compat:a",
        "//buildenv/rule_class_compat:b", "//buildenv/rule_class_restrict:d",
        "//buildenv/foo:b");
    assertThat(supportedEnvironments("a", ruleDef)).containsExactlyElementsIn(expectedEnvironments);
  }

  /**
   * Tests that environments from the same group can't appear in both restriction and
   * compatibility rule class defaults.
   */
  @Test
  public void sameEnvironmentRuleClassCompatibleAndRestricted() throws Exception {
    writeRuleClassDefaultEnvironments();
    reporter.removeHandler(failFastHandler);
    String ruleDef = "bad_rule_class_default(name = 'a')";
    assertThat(scratchConfiguredTarget("hello", "a", ruleDef)).isNull();
    assertContainsEvent("//buildenv/rule_class_compat:a and //buildenv/rule_class_compat:b "
        + "belong to the same environment group");
  }

  /**
   * Tests that a dependency is valid if both rules implicitly inherit all default environments.
   */
  @Test
  public void allDefaults() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule());
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a dependency is valid when both rules explicitly declare the same constraints.
   */
  @Test
  public void sameConstraintsDeclaredExplicitly() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:b")),
        getDependingRule(constrainedTo("//buildenv/foo:b")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a dependency is valid when both the depender and dependency explicitly declare
   * their constraints and the depender supports a subset of the dependency's environments
   */
  @Test
  public void validConstraintsDeclaredExplicitly() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:a", "//buildenv/foo:b")),
        getDependingRule(constrainedTo("//buildenv/foo:b")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a dependency is invalid when both the depender and dependency explicitly declare
   * their constraints and the depender supports an environment the dependency doesn't.
   */
  @Test
  public void invalidConstraintsDeclaredExplicitly() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:b")),
        getDependingRule(constrainedTo("//buildenv/foo:a", "//buildenv/foo:b")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:a");
  }

  /**
   * Tests that a dependency is valid when both rules add the same set of environments to their
   * defaults.
   */
  @Test
  public void sameCompatibilityConstraints() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(compatibleWith("//buildenv/foo:b", "//buildenv/foo:c")),
        getDependingRule(compatibleWith("//buildenv/foo:b", "//buildenv/foo:c")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a dependency is valid when both rules add environments to their defaults and
   * the depender only adds environments also added by the dependency.
   */
  @Test
  public void validCompatibilityConstraints() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(compatibleWith("//buildenv/foo:b", "//buildenv/foo:c")),
        getDependingRule(compatibleWith("//buildenv/foo:c")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a dependency is invalid when both rules add environments to their defaults and
   * the depender adds environments not added by the dependency.
   */
  @Test
  public void invalidCompatibilityConstraints() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(compatibleWith("//buildenv/foo:c")),
        getDependingRule(compatibleWith("//buildenv/foo:b", "//buildenv/foo:c")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:b");
  }

  /**
   * Tests the error message when the dependency is missing multiple expected environments.
   */
  @Test
  public void multipleMissingEnvironments() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule(compatibleWith("//buildenv/foo:b", "//buildenv/foo:c")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent("dependency //hello:dep doesn't support expected environments: "
        + "//buildenv/foo:b, //buildenv/foo:c");
  }

  /**
   * Tests a valid dependency including environments from different groups.
   */
  @Test
  public void validMultigroupConstraints() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    new EnvironmentGroupMaker("buildenv/bar").setEnvironments("d", "e", "f").setDefaults("d")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:b", "//buildenv/foo:c"),
            compatibleWith("//buildenv/bar:e")),
        getDependingRule(constrainedTo("//buildenv/foo:c"), compatibleWith("//buildenv/bar:e")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests an invalid dependency including environments from different groups.
   */
  @Test
  public void invalidMultigroupConstraints() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    new EnvironmentGroupMaker("buildenv/bar").setEnvironments("d", "e", "f").setDefaults("d")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:c"), compatibleWith("//buildenv/bar:e")),
        getDependingRule(constrainedTo("//buildenv/foo:b", "//buildenv/foo:c"),
            compatibleWith("//buildenv/bar:e")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:b");
  }

  /**
   * Tests a valid dependency where the dependency doesn't "know" about the expected environment's
   * group, but implicitly supports it because that environment is a default.
   */
  @Test
  public void validConstraintsUnknownEnvironmentToDependency() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a", "b")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule(constrainedTo("//buildenv/foo:b")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests an invalid dependency where the dependency doesn't "know" about the expected
   * environment's group and doesn't support it because it isn't a default.
   */
  @Test
  public void invalidConstraintsUnknownEnvironmentToDependency() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a", "b")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule(constrainedTo("//buildenv/foo:c")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:c");
  }

  /**
   * Tests a valid dependency where the depender doesn't "know" about one of the dependency's
   * groups, the depender implicitly supports that group's defaults, and all of those defaults
   * are accounted for in the dependency.
   */
  @Test
  public void validConstraintsUnknownEnvironmentToDependender() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:a", "//buildenv/foo:b")),
        getDependingRule());
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests an invalid dependency where the depender doesn't "know" about one of the dependency's
   * groups, the depender implicitly supports that group's defaults, and one of those defaults
   * isn't accounted for in the dependency.
   */
  @Test
  public void invalidConstraintsUnknownEnvironmentToDependender() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:b")),
        getDependingRule());
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:a");
  }

  /**
   * Tests the case where one dependency is valid and another one isn't.
   */
  @Test
  public void oneDependencyIsInvalid() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file("hello/BUILD",
        getRuleDef("sh_library", "bad_dep", constrainedTo("//buildenv/foo:b")),
        getRuleDef("sh_library", "good_dep", compatibleWith("//buildenv/foo:b")),
        getRuleDef("sh_library", "depender",
            constrainedTo("//buildenv/foo:a", "//buildenv/foo:b"),
            getAttrDef("deps", "good_dep", "bad_dep")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:depender")).isNull();
    assertContainsEvent("//hello:bad_dep doesn't support expected environment: //buildenv/foo:a");
    assertDoesNotContainEvent("//hello:good_dep");
  }

  @Test
  public void constraintEnforcementDisabled() throws Exception {
    useConfiguration("--enforce_constraints=0");
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule(compatibleWith("//buildenv/foo:b", "//buildenv/foo:c")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void constraintEnforcementDisabledExecConfig() throws Exception {
    useConfiguration("--enforce_constraints=0");
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults().make();
    scratch.file(
        "hello/BUILD",
        "genrule(",
        "    name = 'gen',",
        "    srcs = [],",
        "    outs = ['gen.out'],",
        "    cmd = '',",
        "    tools = [':main'])",
        getDependencyRule(),
        getDependingRule(compatibleWith("//buildenv/foo:a")));
    assertThat(getConfiguredTarget("//hello:gen")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that package defaults compatibility produces a valid dependency that would otherwise
   * be invalid.
   */
  @Test
  public void compatibilityPackageDefaults() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file("hello/BUILD",
        "package(default_compatible_with = ['//buildenv/foo:b'])",
        getDependencyRule(),
        getDependingRule(compatibleWith("//buildenv/foo:b")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a rule's compatibility declaration overrides its package defaults compatibility.
   */
  @Test
  public void packageDefaultsCompatibilityOverride() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    // We intentionally create an invalid dependency structure vs. a valid one. If we tested on
    // a valid one, this test wouldn't be able to distinguish between rule declarations overriding
    // package defaults and package defaults overriding rule declarations.
    scratch.file("hello/BUILD",
        "package(default_compatible_with = ['//buildenv/foo:b'])",
        getDependencyRule(compatibleWith("//buildenv/foo:a")),
        getDependingRule(compatibleWith("//buildenv/foo:a", "//buildenv/foo:b")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:b");
  }

  /**
   * Tests that package defaults restriction produces a valid dependency that would otherwise be
   * invalid.
   */
  @Test
  public void restrictionPackageDefaults() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a", "b")
        .make();
    scratch.file("hello/BUILD",
        "package(default_restricted_to = ['//buildenv/foo:b'])",
        getDependencyRule(constrainedTo("//buildenv/foo:b")),
        getDependingRule());
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  /**
   * Tests that a rule's restriction declaration overrides its package defaults restriction.
   */
  @Test
  public void packageDefaultsRestrictionOverride() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    // We intentionally create an invalid dependency structure vs. a valid one. If we tested on
    // a valid one, this test wouldn't be able to distinguish between rule declarations overriding
    // package defaults and package defaults overriding rule declarations.
    scratch.file("hello/BUILD",
        "package(default_restricted_to = ['//buildenv/foo:b'])",
        getDependencyRule(constrainedTo("//buildenv/foo:a")),
        getDependingRule(constrainedTo("//buildenv/foo:a", "//buildenv/foo:b")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:b");
  }

  /**
   * Tests that "default_compatible_with" fills in a rule's "compatible_with" when not specified
   * by the rule. This is different than, e.g., the rule declaration / rule class defaults model,
   * where the "compatible_with" / "restricted_to" values of rule class defaults are merged together
   * before being supplied to the rule. See comments in DependencyResolver for more discussion.
   */
  @Test
  public void packageDefaultsDirectlyFillRuleAttributes() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    scratch.file("hello/BUILD",
        "package(default_restricted_to = ['//buildenv/foo:b'])",
        getDependencyRule(compatibleWith("//buildenv/foo:a")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:dep")).isNull();
    assertContainsEvent("//buildenv/foo:a and //buildenv/foo:b belong to the same "
        + "environment group. They should be declared together either here or in restricted_to");
  }

  @Test
  public void hostDependenciesAreNotChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        sh_binary(name = 'host_tool',
            srcs = ['host_tool.sh'],
            restricted_to = ['//buildenv/foo:b'])
        genrule(
            name = 'hello',
            srcs = [],
            outs = ['hello.out'],
            cmd = '',
            tools = [':host_tool'],
            compatible_with = ['//buildenv/foo:a'])
        """);
    assertThat(getConfiguredTarget("//hello:hello")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void hostDependenciesAreNotChecked_customRule() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/rule.bzl",
        """
        def _impl(ctx):
            pass
        my_rule = rule(
            implementation = _impl,
            attrs = {
                'tool': attr.label(cfg = 'exec',),
            },
        )
        """);
    scratch.file(
        "hello/BUILD",
        """
        load(':rule.bzl', 'my_rule')
        sh_binary(name = 'host_tool',
            srcs = ['host_tool.sh'],
            restricted_to = ['//buildenv/foo:b'])
        my_rule(
            name = 'hello',
            tool = ':host_tool',
            compatible_with = ['//buildenv/foo:a'])
        """);
    assertThat(getConfiguredTarget("//hello:hello")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void execDependenciesAreNotChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        sh_binary(name = 'tool',
            srcs = ['tool.sh'],
            restricted_to = ['//buildenv/foo:b'])
        genrule(
            name = 'hello',
            srcs = [],
            outs = ['hello.out'],
            cmd = '',
            tools = [':tool'],
            compatible_with = ['//buildenv/foo:a'])
        """);
    assertThat(getConfiguredTarget("//hello:hello")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void execDependenciesAreNotChecked_customRule() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/rule.bzl",
        """
        def _impl(ctx):
            pass
        my_rule = rule(
            implementation = _impl,
            attrs = {
                'tool': attr.label(cfg = 'exec',),
            },
        )
        """);
    scratch.file(
        "hello/BUILD",
        """
        load(':rule.bzl', 'my_rule')
        sh_binary(name = 'exec_tool',
            srcs = ['exec_tool.sh'],
            restricted_to = ['//buildenv/foo:b'])
        my_rule(
            name = 'hello',
            tool = ':exec_tool',
            compatible_with = ['//buildenv/foo:a'])
        """);
    assertThat(getConfiguredTarget("//hello:hello")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void implicitAndLateBoundDependenciesAreNotChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        rule_with_implicit_and_latebound_deps(
            name = 'hi',
            compatible_with = ['//buildenv/foo:b'])
        """);
    assertThat(getConfiguredTarget("//hello:hi")).isNotNull();
    // Note that the event "cannot build rule_with_implicit_and_latebound_deps" *does* occur
    // because of the implementation of UnknownRuleConfiguredTarget.
    assertDoesNotContainEvent(":implicit doesn't support expected environment");
    assertDoesNotContainEvent(":latebound doesn't support expected environment");
    assertDoesNotContainEvent("normal doesn't support expected environment");
  }

  @Test
  public void implicitDepsWithWhiteListedAttributeAreChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        rule_with_enforced_implicit_deps(
            name = 'hi',
            compatible_with = ['//buildenv/foo:b'])
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:hi")).isNull();
    assertContainsEvent(
        "dependency //helpers:implicit doesn't support expected environment: //buildenv/foo:b");
  }

  @Test
  public void explicitDepWithEnforcementSkipOverride() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        rule_with_skipped_attr(
            name = 'hi',
            some_attr = '//helpers:default',
            compatible_with = ['//buildenv/foo:b'])
        """);
    assertThat(getConfiguredTarget("//hello:hi")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void javaDataAndResourcesAttributesSkipped() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        java_library(
            name = 'hi',
            data = ['//helpers:default'],
            resources = ['//helpers:default'],
            compatible_with = ['//buildenv/foo:b'])
        """);
    assertThat(getConfiguredTarget("//hello:hi")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void filegroupDataAttributesSkipped() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("a").make();
    scratch.file(
        "hello/BUILD",
        """
        filegroup(
            name = 'hi',
            data = ['//helpers:default'],
            compatible_with = ['//buildenv/foo:b'])
        """);
    assertThat(getConfiguredTarget("//hello:hi")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void outputFilesAreChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    scratch.file(
        "hello/BUILD",
        """
        genrule(name = 'gen', srcs = [], outs = ['shlib.sh'], cmd = '')
        sh_library(
            name = 'shlib',
            srcs = ['shlib.sh'],
            data = ['whatever.txt'],
            compatible_with = ['//buildenv/foo:a'])
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:shlib")).isNull();
    assertContainsEvent(
        "dependency //hello:gen doesn't support expected environment: //buildenv/foo:a");
  }

  @Test
  public void configSettingRulesAreNotChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    scratch.file(
        "hello/BUILD",
        """
        sh_library(
            name = 'shlib',
            srcs = select({
                '//config:a': ['shlib.sh'],
            }),
            compatible_with = ['//buildenv/foo:a'])
        """);
    useConfiguration("--define", "mode=a");
    assertThat(getConfiguredTarget("//hello:shlib")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void fulfills() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b")
        .setFulfills("a", "b")
        .setDefaults()
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:a")),
        getDependingRule(constrainedTo("//buildenv/foo:b")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void fulfillsIsNotSymmetric() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b")
        .setFulfills("a", "b")
        .setDefaults()
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:b")),
        getDependingRule(constrainedTo("//buildenv/foo:a")));
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:main")).isNull();
    assertContainsEvent(
        "dependency //hello:dep doesn't support expected environment: //buildenv/foo:a");
  }

  @Test
  public void fulfillsIsTransitive() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b", "c")
        .setFulfills("a", "b")
        .setFulfills("b", "c")
        .setDefaults()
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:a")),
        getDependingRule(constrainedTo("//buildenv/foo:c")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void defaultEnvironmentDirectlyFulfills() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b")
        .setFulfills("a", "b")
        .setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule(constrainedTo("//buildenv/foo:b")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void defaultEnvironmentIndirectlyFulfills() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b", "c")
        .setFulfills("a", "b")
        .setFulfills("b", "c")
        .setDefaults("a")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(),
        getDependingRule(constrainedTo("//buildenv/foo:c")));
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void environmentFulfillsExpectedDefault() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b")
        .setFulfills("a", "b")
        .setDefaults("b")
        .make();
    scratch.file("hello/BUILD",
        getDependencyRule(constrainedTo("//buildenv/foo:a")),
        getDependingRule());
    assertThat(getConfiguredTarget("//hello:main")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void constraintExemptRulesDontHaveConstraintAttributes() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b")
        .setDefaults("a")
        .make();
    scratch.file(
        "ihave/BUILD",
        """
        totally_free_rule(
            name = 'nolimits',
            restricted_to = ['//buildenv/foo:b']
        )
        """);

    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//ihave:nolimits")).isNull();
    assertContainsEvent("no such attribute 'restricted_to' in 'totally_free_rule'");
  }

  @Test
  public void buildingEnvironmentGroupDirectlyDoesntCrash() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b")
        .setDefaults("a")
        .make();
    assertThat(getConfiguredTarget("//buildenv/foo:foo")).isNotNull();
  }

  private void writeDepsForSelectTests() throws Exception {
    scratch.file(
        "deps/BUILD",
        """
        cc_library(
            name = 'dep_a',
            srcs = [],
            restricted_to = ['//buildenv/foo:a'])
        cc_library(
            name = 'dep_b',
            srcs = [],
            restricted_to = ['//buildenv/foo:b'])
        """);
  }

  @Test
  public void selectableDepsCanMissEnvironments() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    assertThat(getConfiguredTarget("//hello:lib")).isNotNull();
  }

  @Test
  public void selectableAliasDepsTreatedLikeOtherDeps() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        alias(
            name = 'deps_a_alias',
            actual = '//deps:dep_a')
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': [':deps_a_alias'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    assertThat(getConfiguredTarget("//hello:lib")).isNotNull();
  }

  @Test
  public void selectableOutputFileDepsTreatedLikeOtherDeps() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        genrule(
            name = 'src_a',
            outs = ['src_a.c'],
            cmd = 'touch $@',
            restricted_to = ['//buildenv/foo:a'])
        cc_library(
            name = 'lib',
            srcs = select({
                '//config:a': [':src_a.c'],
                '//config:b': [],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    assertThat(getConfiguredTarget("//hello:lib")).isNotNull();
  }

  @Test
  public void staticCheckingOnSelectsTemporarilyDisabled() throws Exception {
    // TODO(bazel-team): update this test once static checking on selects is implemented. When
    // that happens, the union of all deps in the select must support the environments in the
    // depending rule. So the logic here is constraint-invalid because //buildenv/foo:c isn't
    // fulfilled by any of the deps.
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b", "c").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b', '//buildenv/foo:c'])
        """);
    useConfiguration("--define", "mode=a");
    assertThat(getConfiguredTarget("//hello:lib")).isNotNull();
  }

  @Test
  public void depInBothSelectAndUnconditionalListIsAlwaysChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            hdrs = ['//deps:dep_a'],
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent(
        "dependency //deps:dep_a doesn't support expected environment: //buildenv/foo:b");
  }

  @Test
  public void unconditionalSelectsAlwaysChecked() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//conditions:default': ['//deps:dep_a'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent(
        "dependency //deps:dep_a doesn't support expected environment: //buildenv/foo:b");
  }

  @Test
  public void refinedEnvironmentCheckingValidCaseDirect() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a'])
        """);
    useConfiguration("--define", "mode=a");
    // Valid because "--define mode=a" refines :lib to "compatible_with = ['//buildenv/foo:a']".
    assertThat(getConfiguredTarget("//hello:lib")).isNotNull();
  }

  @Test
  public void refinedEnvironmentCheckingBadCaseDirect() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    reporter.removeHandler(failFastHandler);
    // Invalid because "--define mode=a" refines :lib to "compatible_with = []" (empty).
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent(
        ""
            + "//hello:lib: the current command line flags disqualify all supported environments "
            + "because of incompatible select() paths:\n"
            + " \n"
            + "  environment: //buildenv/foo:b\n"
            + "    removed by: //hello:lib (/workspace/hello/BUILD:1:11)\n"
            + "    because of a select() that chooses dep: //deps:dep_a\n"
            + "    which lacks: //buildenv/foo:b");
  }

  @Test
  public void refinedEnvironmentCheckingValidCaseTransitive() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        cc_library(
            name = 'depender',
            srcs = [],
            deps = [':lib'],
            compatible_with = ['//buildenv/foo:a'])
        """);
    useConfiguration("--define", "mode=a");
    // Valid because "--define mode=a" refines :lib to "compatible_with = ['//buildenv/foo:a']".
    assertThat(getConfiguredTarget("//hello:depender")).isNotNull();
  }

  @Test
  public void refinedEnvironmentCheckingBadCaseTransitive() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        cc_library(
            name = 'depender',
            srcs = [],
            deps = [':lib'],
            compatible_with = ['//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    reporter.removeHandler(failFastHandler);
    // Invalid because "--define mode=a" refines :lib to "compatible_with = ['//buildenv/foo:a']".
    assertThat(getConfiguredTarget("//hello:depender")).isNull();
    assertContainsEvent(
        "//hello:depender: the current command line flags disqualify all supported environments"
            + " because of incompatible select() paths:\n"
            + " \n"
            + "  environment: //buildenv/foo:b\n"
            + "    removed by: //hello:lib (/workspace/hello/BUILD:1:11)\n"
            + "    because of a select() that chooses dep: //deps:dep_a\n"
            + "    which lacks: //buildenv/foo:b");
  }

  @Test
  public void refinedEnvironmentCheckingBadCaseChooseLowestLevelCulprit() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib2',  # Even though both lib1 and lib2 refine away b, lib2 is the culprit.
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        cc_library(
            name = 'lib1',
            srcs = [],
            deps = select({
                '//config:a': [':lib2'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/foo:b'])
        cc_library(
            name = 'depender',
            srcs = [],
            deps = [':lib1'],
            compatible_with = ['//buildenv/foo:b'])
        """);
    useConfiguration("--define", "mode=a");
    reporter.removeHandler(failFastHandler);
    // Invalid because "--define mode=a" refines :lib to "compatible_with = ['//buildenv/foo:a']".
    assertThat(getConfiguredTarget("//hello:depender")).isNull();
    assertContainsEvent(
        "//hello:depender: the current command line flags disqualify all supported environments"
            + " because of incompatible select() paths:\n"
            + " \n"
            + "  environment: //buildenv/foo:b\n"
            + "    removed by: //hello:lib2 (/workspace/hello/BUILD:1:11)\n"
            + "    because of a select() that chooses dep: //deps:dep_a\n"
            + "    which lacks: //buildenv/foo:b");
  }

  @Test
  public void environmentRefiningAccountsForImplicitDefaults() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults("b").make();
    writeDepsForSelectTests();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }))
        """);
    useConfiguration("--define", "mode=a");
    reporter.removeHandler(failFastHandler);
    // Invalid because :lib has an implicit default of ['//buildenv/foo:b'] and "--define mode=a"
    // refines it to "compatible_with = []" (empty).
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent(
        ""
            + "//hello:lib: the current command line flags disqualify all supported environments "
            + "because of incompatible select() paths:\n"
            + " \n"
            + "  environment: //buildenv/foo:b\n"
            + "    removed by: //hello:lib (/workspace/hello/BUILD:1:11)\n"
            + "    because of a select() that chooses dep: //deps:dep_a\n"
            + "    which lacks: //buildenv/foo:b");
  }

  @Test
  public void environmentRefiningChecksAllEnvironmentGroups() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    new EnvironmentGroupMaker("buildenv/bar").setEnvironments("c", "d").setDefaults().make();
    scratch.file(
        "deps/BUILD",
        """
        cc_library(
            name = 'dep_a',
            srcs = [],
            restricted_to = ['//buildenv/foo:a', '//buildenv/bar:d'])
        cc_library(
            name = 'dep_b',
            srcs = [],
            restricted_to = ['//buildenv/foo:b', '//buildenv/bar:c'])
        """);
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': ['//deps:dep_a'],
                '//config:b': ['//deps:dep_b'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/bar:c'])
        """);
        useConfiguration("--define", "mode=a");
        reporter.removeHandler(failFastHandler);
    // Invalid because while the //buildenv/foo refinement successfully refines :lib to
    // ['//buildenv/foo:a'], the bar refinement refines it to [].
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent(
        ""
            + "//hello:lib: the current command line flags disqualify all supported environments "
            + "because of incompatible select() paths:\n"
            + " \n"
            + "  environment: //buildenv/bar:c\n"
            + "    removed by: //hello:lib (/workspace/hello/BUILD:1:11)\n"
            + "    because of a select() that chooses dep: //deps:dep_a\n"
            + "    which lacks: //buildenv/bar:c");
  }

  /**
   * When multiple environment groups get cleared out by refinement, batch the missing environments
   * by group membership.
   */
  @Test
  public void refinedEnvironmentCheckingPartitionsErrorsbyEnvironmentGroup() throws Exception {
    new EnvironmentGroupMaker("buildenv/foo").setEnvironments("a", "b").setDefaults().make();
    new EnvironmentGroupMaker("buildenv/bar").setEnvironments("c", "d").setDefaults().make();
    scratch.file(
        "hello/BUILD",
        """
        cc_library(
            name = 'all_groups_gone',
            srcs = [],
            restricted_to = ['//buildenv/foo:b', '//buildenv/bar:d'])
        cc_library(
            name = 'all_groups_there',
            srcs = [],
            restricted_to = ['//buildenv/foo:a', '//buildenv/bar:c'])
        cc_library(
            name = 'lib',
            srcs = [],
            deps = select({
                '//config:a': [':all_groups_gone'],
                '//config:b': [':all_groups_there'],
            }),
            compatible_with = ['//buildenv/foo:a', '//buildenv/bar:c'])
        """);
    useConfiguration("--define", "mode=a");
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent(
        ""
            + "//hello:lib: the current command line flags disqualify all supported environments "
            + "because of incompatible select() paths:\n"
            + " \n"
            + "environment group: //buildenv/foo:foo:\n"
            + " \n"
            + "  environment: //buildenv/foo:a\n"
            + "    removed by: //hello:lib (/workspace/hello/BUILD:9:11)\n"
            + "    because of a select() that chooses dep: //hello:all_groups_gone\n"
            + "    which lacks: //buildenv/foo:a\n");

    assertContainsEvent(
        "environment group: //buildenv/bar:bar:\n"
            + " \n"
            + "  environment: //buildenv/bar:c\n"
            + "    removed by: //hello:lib (/workspace/hello/BUILD:9:11)\n"
            + "    because of a select() that chooses dep: //hello:all_groups_gone\n"
            + "    which lacks: //buildenv/bar:c");
  }

  private void writeRulesForRefiningSubsetTests(String topLevelRestrictedTo) throws Exception {
    new EnvironmentGroupMaker("buildenv/foo")
        .setEnvironments("a", "b", "all")
        .setFulfills("all", "a")
        .setFulfills("all", "b")
        .setDefaults()
        .make();
    scratch.file("hello/BUILD",
        "cc_library(",
        "    name = 'lib',",
        "    srcs = [],",
        "    deps = [':dep1'],",
        "    restricted_to = ['//buildenv/foo:" + topLevelRestrictedTo + "'])",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = [],",
        // This is technically illegal because "dep1" declares support for both "a" and "b" but
        // no dependency under the select can provide "b". This is known as "static select
        // constraint checking" and is currently an unimplemented Bazel TODO.
        "    deps = select({",
        "        '//config:a': [':dep2'],",
        "        '//conditions:default': [':dep2'],",
        "    }),",
        "    restricted_to = ['//buildenv/foo:all'])",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = [],",
        "    compatible_with = ['//buildenv/foo:a'])");
  }

  @Test
  public void refiningReplacesRemovedEnvironmentWithValidFulfillingSubset() throws Exception {
    writeRulesForRefiningSubsetTests("a");
    assertThat(getConfiguredTarget("//hello:lib")).isNotNull();
  }

  @Test
  public void refiningReplacesRemovedEnvironmentWithInvalidFulfillingSubset() throws Exception {
    writeRulesForRefiningSubsetTests("b");
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello:lib")).isNull();
    assertContainsEvent("//hello:lib: the current command line flags disqualify all supported "
        + "environments because of incompatible select() paths");
  }

  @Test
  public void invalidSelectKeyError() throws Exception {
    scratch.file(
        "hello/a/BUILD",
        """
        java_library(
            name = 'a',
            runtime_deps = ['//hello/b'],
        )
        """);
    scratch.file(
        "hello/b/BUILD",
        """
        java_library(
            name = 'b',
            runtime_deps = select({'//hello/c': []}),
        )
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//hello/a")).isNull();
    assertContainsEvent(
        "no such package 'hello/c': BUILD file not found in any of the following directories. Add"
            + " a BUILD file to a directory to mark it as a package");
    assertContainsEvent("errors encountered resolving select() keys for //hello/b:b");
  }
}
