// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.analysis;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.util.BuildViewTestBase.AnalysisFailureRecorder;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.DummyTestFragment;
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.Attribute.ComputedDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.RuleClass.ToolchainResolutionMode;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.io.IOException;
import java.util.Collection;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Integration tests for configurable attributes.
 */
@RunWith(JUnit4.class)
public class ConfigurableAttributesTest extends BuildViewTestCase {

  private void writeConfigRules() throws Exception {
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {'foo': 'a'})
        config_setting(
            name = 'b',
            values = {'foo': 'b'})
        """);
  }

  private void writeHelloRules(boolean includeDefaultCondition) throws IOException {
    scratch.file("java/hello/BUILD",
        "java_binary(",
        "    name = 'hello',",
        "    srcs = ['hello.java'],",
        "    deps = select({",
        "        '//conditions:a': [':adep'],",
        "        '//conditions:b': [':bdep'],",
        includeDefaultCondition
            ? "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],"
            : "",
        "    }))",
        "",
        "java_library(",
        "    name = 'adep',",
        "    srcs = ['adep.java'])",
        "java_library(",
        "    name = 'bdep',",
        "    srcs = ['bdep.java'])",
        "java_library(",
        "    name = 'defaultdep',",
        "    srcs = ['defaultdep.java'])");
  }

  private static final String ADEP_INPUT = "bin java/hello/libadep.jar";
  private static final String BDEP_INPUT = "bin java/hello/libbdep.jar";
  private static final String CDEP_INPUT = "bin java/hello/libcdep.jar";
  private static final String DEFAULTDEP_INPUT = "bin java/hello/libdefaultdep.jar";

  /**
   * Checks that, given the specified configuration parameters, the input rule *has* the expected
   * attribute values and *doesn't have* the unexpected attribute values.
   */
  private void checkRule(
      String ruleLabel,
      String attributeName,
      Collection<String> options,
      Iterable<String> expected,
      Iterable<String> notExpected)
      throws Exception {
    useConfiguration(options.toArray(new String[options.size()]));
    ConfiguredTarget binary = getConfiguredTarget(ruleLabel);
    assertThat(binary).isNotNull();
    Set<String> actualDeps = artifactsToStrings(getPrerequisiteArtifacts(binary, attributeName));
    expected.forEach(expectedInput -> assertThat(actualDeps).contains(expectedInput));
    notExpected.forEach(unexpectedInput -> assertThat(actualDeps).doesNotContain(unexpectedInput));
  }

  private void checkRule(String ruleLabel, String option,
      Iterable<String> expected, Iterable<String> notExpected) throws Exception {
    checkRule(ruleLabel, ImmutableList.of(option), expected, notExpected);
  }

  private void checkRule(
      String ruleLabel,
      Collection<String> options,
      Iterable<String> expected,
      Iterable<String> notExpected)
      throws Exception {
    checkRule(ruleLabel, "deps", options, expected, notExpected);
  }

  private static final MockRule RULE_WITH_OUTPUT_ATTR =
      () -> MockRule.define("rule_with_output_attr", attr("out", BuildType.OUTPUT));

  private static final MockRule RULE_WITH_COMPUTED_DEFAULT =
      () -> MockRule.define(
          "rule_with_computed_default",
          attr("string_attr", Type.STRING),
          attr("$computed_attr", Type.STRING).value(
              new ComputedDefault("string_attr") {
                @Override
                public Object getDefault(AttributeMap rule) {
                  return rule.get("string_attr", Type.STRING) + "2";
                }
            }));

  private static final MockRule RULE_WITH_BOOLEAN_ATTR =
      () -> MockRule.define("rule_with_boolean_attr", attr("boolean_attr", Type.BOOLEAN));

  private static final MockRule RULE_WITH_ALLOWED_VALUES =
      () -> MockRule.define(
          "rule_with_allowed_values",
          attr("one_two", Type.STRING)
              .allowedValues(new Attribute.AllowedValueSet("one", "two")));

  private static final MockRule RULE_WITH_LABEL_DEFAULT =
      () ->
          MockRule.define(
              "rule_with_label_default",
              (builder, env) ->
                  builder.add(
                      attr("dep", BuildType.LABEL)
                          .value(Label.parseCanonicalUnchecked("//foo:default"))
                          .allowedFileTypes(FileTypeSet.ANY_FILE)));

  private static final MockRule RULE_WITH_NO_PLATFORM =
      () ->
          MockRule.define(
              "rule_with_no_platform",
              (builder, env) ->
                  builder
                      .add(attr("deps", LABEL_LIST).allowedFileTypes())
                      .useToolchainResolution(ToolchainResolutionMode.DISABLED));

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder =
        new ConfiguredRuleClassProvider.Builder()
            .addRuleDefinition(RULE_WITH_OUTPUT_ATTR)
            .addRuleDefinition(RULE_WITH_COMPUTED_DEFAULT)
            .addRuleDefinition(RULE_WITH_BOOLEAN_ATTR)
            .addRuleDefinition(RULE_WITH_ALLOWED_VALUES)
            .addRuleDefinition(RULE_WITH_LABEL_DEFAULT)
            .addRuleDefinition(RULE_WITH_NO_PLATFORM);
    TestRuleClassProvider.addStandardRules(builder);
    // Allow use of --foo as a dummy flag
    builder.addConfigurationFragment(DummyTestFragment.class);
    return builder.build();
  }

  @Before
  public void setupStarlarkJavaBinary() throws Exception {
    setBuildLanguageOptions("--experimental_google_legacy_api");
  }

  @Test
  public void basicConfigurability() throws Exception {
    writeHelloRules(/*includeDefaultCondition=*/true);
    writeConfigRules();
    checkRule(
        "//java/hello:hello",
        "--foo=a",
        /*expected:*/ ImmutableList.of(ADEP_INPUT),
        /*not expected:*/ ImmutableList.of(BDEP_INPUT, DEFAULTDEP_INPUT));
    checkRule(
        "//java/hello:hello",
        "--foo=b",
        /*expected:*/ ImmutableList.of(BDEP_INPUT),
        /*not expected:*/ ImmutableList.of(ADEP_INPUT, DEFAULTDEP_INPUT));
  }

  @Test
  public void configurabilityDefaults() throws Exception {
    writeHelloRules(/*includeDefaultCondition=*/true);
    writeConfigRules();
    checkRule(
        "//java/hello:hello",
        "--foo=something_random",
        /*expected:*/ ImmutableList.of(DEFAULTDEP_INPUT),
        /*not expected:*/ ImmutableList.of(ADEP_INPUT, BDEP_INPUT));
    checkRule("//java/hello:hello", "",
        /*expected:*/ ImmutableList.of(DEFAULTDEP_INPUT),
        /*not expected:*/ ImmutableList.of(ADEP_INPUT, BDEP_INPUT));
  }

  /**
   * Duplicate label definitions are fine as long as they're in different selection branches.
   */
  @Test
  public void depsWithDuplicatesInDifferentBranches() throws Exception {
    writeConfigRules();
    scratch.file("java/hello/BUILD",
        "java_binary(",
        "    name = 'hello',",
        "    srcs = ['hello.java'],",
        "    deps = select({",
        "        '//conditions:a': [':adep', ':cdep'],",
        "        '//conditions:b': [':bdep', ':cdep'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],",
        "    }))",
        "",
        "java_library(",
        "    name = 'adep',",
        "    srcs = ['adep.java'])",
        "java_library(",
        "    name = 'bdep',",
        "    srcs = ['bdep.java'])",
        "java_library(",
        "    name = 'cdep',",
        "    srcs = ['cdep.java'])");
    checkRule(
        "//java/hello:hello",
        "--foo=a",
        /*expected:*/ ImmutableList.of(ADEP_INPUT, CDEP_INPUT),
        /*not expected:*/ ImmutableList.of(BDEP_INPUT, DEFAULTDEP_INPUT));
  }

  /**
   * Duplicate label definitions are *not* fine within the same branch.
   */
  @Test
  public void depsWithDuplicatesInSameBranch() throws Exception {
    writeConfigRules();
    scratch.file("java/hello/BUILD",
        "java_binary(",
        "    name = 'hello',",
        "    srcs = ['hello.java'],",
        "    deps = select({",
        "        '//conditions:a': [':adep', ':cdep', ':adep'],",
        "        '//conditions:b': [':bdep', ':cdep'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],",
        "    }))",
        "",
        "java_library(",
        "    name = 'adep',",
        "    srcs = ['adep.java'])",
        "java_library(",
        "    name = 'bdep',",
        "    srcs = ['bdep.java'])",
        "java_library(",
        "    name = 'cdep',",
        "    srcs = ['cdep.java'])");

    reporter.removeHandler(failFastHandler); // Expect errors.
    useConfiguration("--foo=a");
    getConfiguredTarget("//java/hello:hello");
    assertContainsEvent(
        "Label '//java/hello:adep' is duplicated in the 'deps' attribute of rule 'hello'");
  }

  /**
   * When an attribute includes multiple selects, we don't allow duplicates even across
   * selects (this saves us from having to do possibly expensive value iteration since the
   * number of values can grow exponentially with respect to the number of selects).
   */
  @Test
  public void duplicatesAcrossMultipleSelects() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/hello/BUILD",
        """
        java_binary(
            name = 'hello',
            srcs = select({
                '//conditions:a': ['a.java'],
                '//conditions:b': ['b.java'],
                })
                + select({
                '//conditions:a': ['a.java'],
                '//conditions:b': ['c.java'],
            }))
        """);

    reporter.removeHandler(failFastHandler); // Expect errors.
    useConfiguration("--foo=a");
    getConfiguredTarget("//java/hello:hello");
    assertContainsEvent(
        "in srcs attribute of java_binary rule //java/hello:hello: Label '//java/hello:a.java' is"
            + " duplicated");
  }

  /**
   * Even with multiple selects, duplicates are allowed within a *single* select as long as
   * they're in different branches (and thus mutually exclusive).
   */
  @Test
  public void duplicatesInDifferentBranchesMultipleSelects() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/hello/BUILD",
        """
        java_binary(
            name = 'hello',
            srcs = select({
                '//conditions:a': ['a.java'],
                '//conditions:b': ['a.java'],
                })
                + select({
                '//conditions:a': ['b.java'],
                '//conditions:b': ['b.java'],
            }))
        """);

    useConfiguration("--foo=a");
    getConfiguredTarget("//java/hello:hello");
    assertNoEvents();
  }

  /**
   * With multiple selects, a single select still can't duplicate labels within the same branch.
   */
  @Test
  public void duplicatesInSameBranchMultipleSelects() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/hello/BUILD",
        """
        java_binary(
            name = 'hello',
            srcs = select({
                '//conditions:a': ['a.java', 'a.java'],
                '//conditions:b': ['b.java'],
                })
                + select({
                '//conditions:a': ['c.java'],
                '//conditions:b': ['d.java'],
            }))
        """);

    reporter.removeHandler(failFastHandler); // Expect errors.
    useConfiguration("--foo=a");
    getConfiguredTarget("//java/hello:hello");
    assertContainsEvent(
        "Label '//java/hello:a.java' is duplicated in the 'srcs' attribute of rule 'hello'");
  }

  /**
   * Attributes of type {@link BuildType#OUTPUT} are not configurable.
   */
  @Test
  public void outputTypeNotConfigurable() throws Exception {
    writeConfigRules();
    scratch.file("foo/BUILD",
        "rule_with_output_attr(",
        "    name = 'has_an_out',",
        "    out = select({",
        "        '//conditions:a': 'a.out',",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': 'default.out'})",
        ")");

    reporter.removeHandler(failFastHandler); // Expect errors.
    getConfiguredTarget("//foo:has_an_out");
    assertContainsEvent("attribute \"out\" is not configurable");
  }

  /**
   * Attributes of type {@link BuildType#OUTPUT_LIST} are not configurable.
   */
  @Test
  public void outputListTypeNotConfigurable() throws Exception {
    writeConfigRules();
    scratch.file("foo/BUILD",
        "genrule(",
        "    name = 'generator',",
        "    srcs = [],",
        "    outs = select({",
        "        '//conditions:a': ['a.out'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': ['default.out']})",
        ")");

    reporter.removeHandler(failFastHandler); // Expect errors.
    getConfiguredTarget("//foo:generator");
    assertContainsEvent("attribute \"outs\" is not configurable");
  }

  /**
   * Tests that computed defaults faithfully reflect the values of the attributes they depend on.
   */
  @Test
  public void computedDefaults() throws Exception {
    writeConfigRules();
    scratch.file("test/BUILD",
        "rule_with_computed_default(",
        "    name = 'the_rule',",
        "    string_attr = select({",
        "        '//conditions:a': 'a',",
        "        '//conditions:b': 'b',",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': 'default',",
        "    }))");

    // Configuration a:
    useConfiguration("--foo=a");
    ConfiguredTargetAndData binary = getConfiguredTargetAndData("//test:the_rule");
    AttributeMap attributes = getMapperFromConfiguredTargetAndTarget(binary);
    assertThat(attributes.get("$computed_attr", Type.STRING)).isEqualTo("a2");

    // configuration b:
    useConfiguration("--foo=b");
    binary = getConfiguredTargetAndData("//test:the_rule");
    attributes = getMapperFromConfiguredTargetAndTarget(binary);
    assertThat(attributes.get("$computed_attr", Type.STRING)).isEqualTo("b2");
  }

  @Test
  public void configKeyTypeChecking_Int() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "java/foo/BUILD",
        """
        java_library(
            name = 'int_key',
            srcs = select({123: ['a.java']})
        )
        """);
    assertTargetError(
        "//java/foo:int_key", "select: got int for dict key, want a Label or label string");
  }

  @Test
  public void configKeyTypeChecking_Bool() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "java/foo/BUILD",
        """
        java_library(
            name = 'bool_key',
            srcs = select({True: ['a.java']})
        )
        """);
    assertTargetError(
        "//java/foo:bool_key", "select: got bool for dict key, want a Label or label string");
  }

  @Test
  public void configKeyTypeChecking_None() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "java/foo/BUILD",
        """
        java_library(
            name = 'none_key',
            srcs = select({None: ['a.java']})
        )
        """);
    assertTargetError(
        "//java/foo:none_key", "select: got NoneType for dict key, want a Label or label string");
  }

  @Test
  public void selectWithoutConditionsMakesNoSense() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "foo/BUILD",
        """
        genrule(
            name = 'nothing',
            srcs = [],
            outs = ['notmuch'],
            cmd = select({})
        )
        """);
    assertTargetError(
        "//foo:nothing",
        "select({}) with an empty dictionary can never resolve because it includes no conditions "
            + "to match");
  }

  /**
   * Tests that config keys must resolve to existent targets.
   */
  @Test
  public void missingConfigKey() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    // Only create one of two necessary configurability rules:
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {'foo': 'a'})
        """);
    writeHelloRules(/*includeDefaultCondition=*/true);
    getConfiguredTarget("//java/hello:hello");
    assertContainsEvent("no such target '//conditions:b'");
  }

  /**
   * Tests that config keys must resolve to config_setting targets.
   */
  @Test
  public void invalidConfigKey() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {'foo': 'a'})
        rule_with_output_attr(
            name = 'b',
            out = 'b.out')
        """);
    writeHelloRules(/*includeDefaultCondition=*/true);
    assertThat(getConfiguredTarget("//java/hello:hello")).isNull();
    assertContainsEvent("//conditions:b is not a valid select() condition for //java/hello:hello");
    assertDoesNotContainEvent("//conditions:a"); // This one is legitimate..
  }

  @Test
  public void configKeyNonexistentTarget() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "foo/BUILD",
        """
        genrule(
            name = 'g',
            outs = ['g.out'],
            cmd = select({':fake': ''})
        )
        """);
    assertThat(getConfiguredTarget("//foo:g")).isNull();
    assertContainsEvent("//foo:fake is not a valid select() condition for //foo:g");
  }

  @Test
  public void configKeyNonexistentTarget_otherPackage() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {'foo': 'a'})
        """);
    scratch.file("bar/BUILD");
    scratch.file(
        "foo/BUILD",
        """
        genrule(
            name = 'g',
            outs = ['g.out'],
            # With an invalid target and a real target, validate skyframe error handling.
            # See http://b/162021059 for details.
            cmd = select({'//bar:fake': '', '//conditions:a': ''})
        )
        """);
    assertThat(getConfiguredTarget("//foo:g")).isNull();
    assertContainsEvent("bar/BUILD: no such target '//bar:fake'");
    assertContainsEvent("foo/BUILD:1:8: errors encountered resolving select() keys for //foo:g");
  }

  /**
   * Tests config keys with multiple requirements.
   */
  @Test
  public void multiConditionConfigKeys() throws Exception {
    writeHelloRules(/*includeDefaultCondition=*/true);
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {
                'foo': 'a',
                'compilation_mode': 'dbg'
            })
        config_setting(
            name = 'b',
            values = {'foo': 'b'})
        """);
    checkRule(
        "//java/hello:hello",
        "--foo=a",
        /*expected:*/ ImmutableList.of(DEFAULTDEP_INPUT),
        /*not expected:*/ ImmutableList.of(ADEP_INPUT, BDEP_INPUT));
    checkRule(
        "//java/hello:hello",
        ImmutableList.of("--foo=a", "--compilation_mode=dbg"),
        /*expected:*/ ImmutableList.of(ADEP_INPUT),
        /*not expected:*/ ImmutableList.of(BDEP_INPUT, DEFAULTDEP_INPUT));
  }

  /**
   * Tests that changing a config_setting invalidates the rule that uses it.
   */
  @Test
  public void configKeyInvalidation() throws Exception {
    writeHelloRules(/*includeDefaultCondition=*/true);
    writeConfigRules();

    // Iteration 1: --test_args=a should apply //conditions:a.
    useConfiguration("--foo=a");
    checkRule(
        "//java/hello:hello",
        "--foo=a",
        /*expected:*/ ImmutableList.of(ADEP_INPUT),
        /*not expected:*/ ImmutableList.of(BDEP_INPUT, DEFAULTDEP_INPUT));

    // Rewrite the condition for //conditions:a.
    scratch.overwriteFile(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {'foo': 'c'})
        config_setting(
            name = 'b',
            values = {'foo': 'b'})
        """);

    // Iteration 2: same exact analysis should now apply the default condition.
    invalidatePackages();
    checkRule(
        "//java/hello:hello",
        "--foo=a",
        /*expected:*/ ImmutableList.of(DEFAULTDEP_INPUT),
        /*not expected:*/ ImmutableList.of(ADEP_INPUT, BDEP_INPUT));
  }

  /**
   * Tests that multiple matches are not allowed for conditions where one is not a specialization
   * of the other.
   */
  @Test
  public void multipleMatches() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'dup1',
            values = {'compilation_mode': 'opt'})
        config_setting(
            name = 'dup2',
            values = {'define': 'foo=bar'})
        """);
    scratch.file("a/BUILD",
        "genrule(",
        "    name = 'gen',",
        "    cmd = '',",
        "    outs = ['gen.out'],",
        "    srcs = select({",
        "        '//conditions:dup1': ['a.in'],",
        "        '//conditions:dup2': ['b.in'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':default.in'],",
        "    }))");
    useConfiguration("-c", "opt", "--define", "foo=bar");
    assertThat(getConfiguredTarget("//a:gen")).isNull();
    assertContainsEvent(
        "Illegal ambiguous match on configurable attribute \"srcs\" in //a:gen:\n"
            + "//conditions:dup1\n"
            + "//conditions:dup2\n"
            + "Multiple matches are not allowed unless one is unambiguously more specialized "
            + "or they resolve to the same value.");
  }

  /**
   * Tests that when multiple conditions match and for every matching pair, one is
   * a specialization of the other, the most specialized match is chosen.
   */
  @Test
  public void multipleMatchesConditionAndSubcondition() throws Exception {
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'generic',
            values = {'compilation_mode': 'opt'})
        config_setting(
            name = 'precise',
            values = {'compilation_mode': 'opt', 'define': 'foo=bar'})
        config_setting(
            name = 'most_precise',
            values = {'compilation_mode': 'opt', 'define': 'foo=bar', 'foo': 'baz'})
        """);
    scratch.file(
        "java/a/BUILD",
        """
        java_binary(
            name = 'binary',
            srcs = ['binary.java'],
            deps = select({
                '//conditions:generic': [':generic'],
                '//conditions:precise': [':precise'],
                '//conditions:most_precise': [':most_precise'],
            }))
        java_library(
            name = 'generic',
            srcs = ['generic.java'])
        java_library(
            name = 'precise',
            srcs = ['precise.java'])
        java_library(
            name = 'most_precise',
            srcs = ['most_precise.java'])
        """);
    checkRule(
        "//java/a:binary",
        ImmutableList.of("-c", "opt", "--define", "foo=bar", "--foo", "baz"),
        /*expected:*/ ImmutableList.of("bin java/a/libmost_precise.jar"),
        /*not expected:*/ ImmutableList.of(
            "bin java/a/libgeneric.jar", "bin java/a/libprecise.jar"));
  }

  /** Tests that multiple matches are allowed for conditions where the value is the same. */
  @Test
  public void multipleMatchesSameValue() throws Exception {
    reporter.removeHandler(failFastHandler); // Expect errors.
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'dup1',
            values = {'compilation_mode': 'opt'})
        config_setting(
            name = 'dup2',
            values = {'define': 'foo=bar'})
        """);
    scratch.file(
        "a/BUILD",
        "genrule(",
        "    name = 'gen',",
        "    cmd = '',",
        "    outs = ['gen.out'],",
        "    srcs = select({",
        "        '//conditions:dup1': ['a.in'],",
        "        '//conditions:dup2': ['a.in'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':default.in'],",
        "    }))");
    checkRule(
        "//a:gen",
        "srcs",
        ImmutableList.of("-c", "opt", "--define", "foo=bar"),
        /*expected:*/ ImmutableList.of("src a/a.in"),
        /*not expected:*/ ImmutableList.of("src a/default.in"));
  }

  /**
   * Tests that when multiple conditions match but one condition is more specialized than the
   * others, it is chosen and there is no error.
   */
  @Test
  public void multipleMatchesUnambiguous() throws Exception {
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = 'a',
            values = {'define': 'a=1'})
        config_setting(
            name = 'b',
            values = {'compilation_mode': 'opt'})
        config_setting(
            name = 'c',
            values = {'foo': 'baz'})
        config_setting(
            name = 'b_a_c',  # Named to come alphabetically after a and b but before c.
            values = {'define': 'a=1', 'foo': 'baz', 'compilation_mode': 'opt'})
        """);
    scratch.file(
        "java/a/BUILD",
        """
        java_binary(
            name = 'binary',
            srcs = ['binary.java'],
            deps = select({
                '//conditions:a': [':a'],
                '//conditions:b': [':b'],
                '//conditions:c': [':c'],
                '//conditions:b_a_c': [':b_a_c'],
            }))
        java_library(
            name = 'a',
            srcs = ['a.java'])
        java_library(
            name = 'b',
            srcs = ['b.java'])
        java_library(
            name = 'c',
            srcs = ['c.java'])
        java_library(
            name = 'b_a_c',
            srcs = ['b_a_c.java'])
        """);
    checkRule(
        "//java/a:binary",
        ImmutableList.of("--define", "a=1", "--compilation_mode", "opt", "--foo", "baz"),
        /*expected:*/ ImmutableList.of("bin java/a/libb_a_c.jar"),
        /*not expected:*/ ImmutableList.of(
            "bin java/a/liba.jar", "bin java/a/libb.jar", "bin java/a/libc.jar"));
  }

  /** Tests that default conditions are only required when no main condition matches. */
  @Test
  public void noDefaultCondition() throws Exception {
    writeHelloRules(/*includeDefaultCondition=*/false);
    writeConfigRules();

    // An explicit configuration matches: all is well.
    checkRule(
        "//java/hello:hello",
        "--foo=a",
        /*expected:*/ ImmutableList.of(ADEP_INPUT),
        /*not expected:*/ ImmutableList.of(BDEP_INPUT, DEFAULTDEP_INPUT));

    // Nothing matches: expect an error.
    reporter.removeHandler(failFastHandler);
    useConfiguration("");
    assertThat(getConfiguredTarget("//java/hello:hello")).isNull();
    assertContainsEvent(
        "configurable attribute \"deps\" in //java/hello:hello doesn't match this configuration");
  }

  @Test
  public void noMatchCustomErrorMessage() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/hello/BUILD",
        """
        java_binary(
            name = 'hello_default_no_match_error',
            srcs = select({
                '//conditions:a': ['not_chosen.java'],
            }))
        java_binary(
            name = 'hello_custom_no_match_error',
            srcs = select({
                '//conditions:a': ['not_chosen.java'],
            },
            no_match_error = 'You always have to choose condition a!'
        ))
        """);

    reporter.removeHandler(failFastHandler);
    AnalysisFailureRecorder analysisFailureRecorder = new AnalysisFailureRecorder();
    eventBus.register(analysisFailureRecorder);
    useConfiguration("");

    assertThat(getConfiguredTarget("//java/hello:hello_default_no_match_error")).isNull();
    assertContainsEvent(
        "configurable attribute \"srcs\" in //java/hello:hello_default_no_match_error doesn't"
            + " match this configuration. Would a default condition help?\n"
            + "\n"
            + "Conditions checked:");
    // Verify a Root Cause is reported when a target cannot be configured due to no matching config.
    assertThat(analysisFailureRecorder.causes).hasSize(1);
    AnalysisRootCauseEvent rootCause = analysisFailureRecorder.causes.get(0);
    assertThat(rootCause.getLabel())
        .isEqualTo(Label.parseCanonical("//java/hello:hello_default_no_match_error"));

    eventBus.unregister(analysisFailureRecorder);
    analysisFailureRecorder = new AnalysisFailureRecorder();
    eventBus.register(analysisFailureRecorder);
    eventCollector.clear();

    assertThat(getConfiguredTarget("//java/hello:hello_custom_no_match_error")).isNull();
    assertContainsEvent(
        "configurable attribute \"srcs\" in //java/hello:hello_custom_no_match_error doesn't match "
            + "this configuration: You always have to choose condition a!");
    // Verify a Root Cause is reported when a target cannot be configured due to no matching config.
    assertThat(analysisFailureRecorder.causes).hasSize(1);
    rootCause = analysisFailureRecorder.causes.get(0);
    assertThat(rootCause.getLabel())
        .isEqualTo(Label.parseCanonical("//java/hello:hello_custom_no_match_error"));
  }

  @Test
  public void nativeTypeConcatenatedWithSelect() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/foo/rule.bzl",
        """
        def _rule_impl(ctx):
            return []
        myrule = rule(
            implementation = _rule_impl,
            attrs = {
                'deps': attr.label_keyed_string_dict()
            },
        )
        """);
    scratch.file(
        "java/foo/BUILD",
        """
        load(':rule.bzl', 'myrule')
        myrule(
            name = 'mytarget',
            deps = {':always': 'always'} | select({
                '//conditions:a': {':a': 'a'},
                '//conditions:b': {':b': 'b'},
            })
        )
        java_binary(
            name = 'binary',
            srcs = ['binary.java'],
            deps = [':always'] + select({
                '//conditions:a': [':a'],
                '//conditions:b': [':b'],
            })
        )
        java_library(
            name = 'always',
            srcs = ['always.java'])
        java_library(
            name = 'a',
            srcs = ['a.java'])
        java_library(
            name = 'b',
            srcs = ['b.java'])
        """);

    checkRule(
        "//java/foo:binary",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libalways.jar", "bin java/foo/libb.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar"));

    checkRule(
        "//java/foo:mytarget",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libalways.jar", "bin java/foo/libb.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar"));
  }

  @Test
  public void selectConcatenatedWithNativeType() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/foo/rule.bzl",
        """
        def _rule_impl(ctx):
            return []
        myrule = rule(
            implementation = _rule_impl,
            attrs = {
                'deps': attr.label_keyed_string_dict()
            },
        )
        """);
    scratch.file(
        "java/foo/BUILD",
        """
        load(':rule.bzl', 'myrule')
        myrule(
            name = 'mytarget',
            deps = select({
                '//conditions:a': {':a': 'a'},
                '//conditions:b': {':b': 'b'},
            }) | {':always': 'always'}
        )
        java_binary(
            name = 'binary',
            srcs = ['binary.java'],
            deps = select({
                '//conditions:a': [':a'],
                '//conditions:b': [':b'],
            }) + [':always'])
        java_library(
            name = 'always',
            srcs = ['always.java'])
        java_library(
            name = 'a',
            srcs = ['a.java'])
        java_library(
            name = 'b',
            srcs = ['b.java'])
        """);

    checkRule(
        "//java/foo:binary",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libalways.jar", "bin java/foo/libb.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar"));

    checkRule(
        "//java/foo:mytarget",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libalways.jar", "bin java/foo/libb.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar"));
  }

  @Test
  public void selectConcatenatedWithSelect() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/foo/rule.bzl",
        """
        def _rule_impl(ctx):
            return []
        myrule = rule(
            implementation = _rule_impl,
            attrs = {
                'deps': attr.label_keyed_string_dict()
            },
        )
        """);
    scratch.file(
        "java/foo/BUILD",
        """
        load(':rule.bzl', 'myrule')
        myrule(
            name = 'mytarget',
            deps = select({
                '//conditions:a': {':a': 'a'},
                '//conditions:b': {':b': 'b'},
            }) | select({
                '//conditions:a': {':a2': 'a2'},
                '//conditions:b': {':b2': 'b2'},
            })
        )
        java_binary(
            name = 'binary',
            srcs = ['binary.java'],
            deps = select({
                '//conditions:a': [':a'],
                '//conditions:b': [':b'],
            }) + select({
                '//conditions:a': [':a2'],
                '//conditions:b': [':b2'],
            })
        )
        java_library(
            name = 'a',
            srcs = ['a.java'])
        java_library(
            name = 'b',
            srcs = ['b.java'])
        java_library(
            name = 'a2',
            srcs = ['a2.java'])
        java_library(
            name = 'b2',
            srcs = ['b2.java'])
        """);

    checkRule(
        "//java/foo:binary",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libb.jar", "bin java/foo/libb2.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar", "bin java/foo/liba2.jar"));

    checkRule(
        "//java/foo:mytarget",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libb.jar", "bin java/foo/libb2.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar", "bin java/foo/liba2.jar"));
  }

  @Test
  public void dictsWithSameKey() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/foo/rule.bzl",
        """
        def _rule_impl(ctx):
            outputs = []
            for target, value in ctx.attr.deps.items():
                output = ctx.actions.declare_file(target.label.name + value)
                ctx.actions.write(content = value, output = output)
                outputs.append(output)
            return [DefaultInfo(files=depset(outputs))]
        myrule = rule(
            implementation = _rule_impl,
            attrs = {
                'deps': attr.label_keyed_string_dict()
            },
        )
        """);
    scratch.file(
        "java/foo/BUILD",
        """
        load(':rule.bzl', 'myrule')
        myrule(
            name = 'mytarget',
            deps = select({
                '//conditions:a': {':a': 'a'},
            }) | select({
                '//conditions:a': {':a': 'a2'},
            })
        )
        java_library(
            name = 'a',
            srcs = ['a.java']
        )
        filegroup(
            name = 'group',
            srcs = [':mytarget'],
        )
        """);

    checkRule(
        "//java/foo:group",
        "srcs",
        ImmutableList.of("--foo=a"),
        /*expected:*/ ImmutableList.of("bin java/foo/aa2"),
        /*not expected:*/ ImmutableList.of("bin java/foo/aa"));
  }

  @Test
  public void selectConcatenatedWithNonSupportingType() throws Exception {
    writeConfigRules();
    scratch.file(
        "foo/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = 0 + select({
                '//conditions:a': 0,
                '//conditions:b': 1,
            }))
        """);

    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//foo:binary")).isNull();
    assertContainsEvent("type 'boolean' doesn't support select concatenation");
  }

  @Test
  public void concatenationWithDifferentTypes() throws Exception {
    writeConfigRules();
    scratch.file(
        "java/foo/BUILD",
        """
        java_binary(
            name = 'binary',
            srcs = select({
                '//conditions:a': ['a.java'],
                '//conditions:b': ['b.java'],
            }) + 'always.java'
        )
        """);

    reporter.removeHandler(failFastHandler);
    assertThrows(NoSuchTargetException.class, () -> getTarget("//java/foo:binary"));
    assertContainsEvent("Cannot combine incompatible types");
  }

  @Test
  public void selectsWithGlobs() throws Exception {
    writeConfigRules();
    scratch.file("java/foo/globbed/ceecee.java");
    scratch.file(
        "java/foo/BUILD",
        """
        java_binary(
            name = 'binary',
            srcs = glob(['globbed/*.java']) + select({
                '//conditions:a': ['a.java'],
                '//conditions:b': ['b.java'],
            }))
        """);

    useConfiguration("--foo=b");
    ConfiguredTarget binary = getConfiguredTarget("//java/foo:binary");
    assertThat(binary).isNotNull();
    Set<String> sources = artifactsToStrings(getPrerequisiteArtifacts(binary, "srcs"));
    assertThat(sources).contains("src java/foo/b.java");
    assertThat(sources).contains("src java/foo/globbed/ceecee.java");
    assertThat(sources).doesNotContain("src java/foo/a.java");
  }

  @Test
  public void selectsWithGlobsWrongType() throws Exception {
    writeConfigRules();
    scratch.file(
        "foo/BUILD",
        """
        genrule(
            name = 'gen',
            srcs = [],
            outs = ['gen.out'],
            cmd = 'echo' + select({
                '//conditions:a': 'a',
                '//conditions:b': 'b',
            }) + glob(['globbed.java'], allow_empty = True))
        """);

    reporter.removeHandler(failFastHandler);
    assertThrows(NoSuchTargetException.class, () -> getTarget("//foo:binary"));
    assertContainsEvent("Cannot combine incompatible types");
  }

  @Test
  public void globsInSelect() throws Exception {
    writeConfigRules();
    scratch.file("java/foo/globbed/ceecee.java");
    scratch.file(
        "java/foo/BUILD",
        """
        java_binary(
            name = 'binary',
            srcs = ['binary.java'] + select({
                '//conditions:a': glob(['globbed/*.java']),
                '//conditions:b': ['b.java'],
            }))
        """);

    useConfiguration("--foo=a");
    ConfiguredTarget binary = getConfiguredTarget("//java/foo:binary");
    assertThat(binary).isNotNull();
    Set<String> sources = artifactsToStrings(getPrerequisiteArtifacts(binary, "srcs"));
    assertThat(sources).contains("src java/foo/binary.java");
    assertThat(sources).contains("src java/foo/globbed/ceecee.java");
    assertThat(sources).doesNotContain("src java/foo/b.java");
  }

  @Test
  public void selectAcceptedInAttributeWithAllowedValues() throws Exception {
    scratch.file(
        "foo/BUILD",
        """
        rule_with_allowed_values(
            name = 'rule',
            one_two = select({
                '//conditions:default': 'one',
            }))
        """);
    assertThat(getConfiguredTarget("//foo:rule")).isNotNull();
  }

  @Test
  public void selectWithNonAllowedValueCausesError() throws Exception {
    scratch.file(
        "foo/BUILD",
        """
        rule_with_allowed_values(
            name = 'rule',
            one_two = select({
                '//conditions:default': 'TOTALLY_ILLEGAL_VALUE',
            }))
        """);
    reporter.removeHandler(failFastHandler); // Expect errors.
    getConfiguredTarget("//foo:rule");
    assertContainsEvent(
        "invalid value in 'one_two' attribute: "
        + "has to be one of 'one' or 'two' instead of 'TOTALLY_ILLEGAL_VALUE'");
  }

  @Test
  public void selectWithMultipleNonAllowedValuesCausesMultipleErrors() throws Exception {
    scratch.file(
        "foo/BUILD",
        """
        rule_with_allowed_values(
            name = 'rule',
            one_two = select({
                '//conditions:a': 'TOTALLY_ILLEGAL_VALUE',
                '//conditions:default': 'DIFFERENT_BUT_STILL_ILLEGAL',
            }))
        """);
    reporter.removeHandler(failFastHandler); // Expect errors.
    getConfiguredTarget("//foo:rule");
    assertContainsEvent(
        "invalid value in 'one_two' attribute: "
        + "has to be one of 'one' or 'two' instead of 'TOTALLY_ILLEGAL_VALUE'");
    assertContainsEvent(
        "invalid value in 'one_two' attribute: "
        + "has to be one of 'one' or 'two' instead of 'DIFFERENT_BUT_STILL_ILLEGAL'");
  }

  @Test
  public void selectConcatenationWithAllowedValues() throws Exception {
    scratch.file(
        "foo/BUILD",
        """
        rule_with_allowed_values(
            name = 'rule',
            one_two = 'on' + select({
                '//conditions:default': 'e',
            }))
        """);
    assertThat(getConfiguredTarget("//foo:rule")).isNotNull();
  }

  @Test
  public void selectConcatenationWithNonAllowedValues() throws Exception {
    scratch.file(
        "foo/BUILD",
        """
        rule_with_allowed_values(
            name = 'rule',
            one_two = 'on' + select({
                '//conditions:default': 'o',
            }))
        """);
    reporter.removeHandler(failFastHandler); // Expect errors.
    getConfiguredTarget("//foo:binary");
    assertContainsEvent(
        "invalid value in 'one_two' attribute: "
        + "has to be one of 'one' or 'two' instead of 'ono'");
  }

  @Test
  public void computedDefaultAttributesCanReferenceConfigurableAttributes() throws Exception {
    scratch.file(
        "test/selector_rules.bzl",
        """
        def _impl(ctx):
          ctx.actions.write(
              output=ctx.outputs.out_file,
              content=ctx.attr.string_value,
          )
          return []

        def _derived_value(string_value):
          return Label("//test:%s" % string_value)

        selector_rule = rule(
          attrs = {
              "string_value": attr.string(default = ""),
              "out_file": attr.output(),
              "_derived": attr.label(default = _derived_value),
          },
        implementation = _impl,
        )
        """);
    scratch.file("test/BUILD",
        "genrule(name = \"foo\", srcs = [], outs = [\"foo.out\"], cmd = \"\")");
    scratch.file(
        "foo/BUILD",
        """
        load('//test:selector_rules.bzl', "selector_rule")
        selector_rule(
            name = "rule",
            out_file = "rule.out",
            string_value = select({"//conditions:default": "foo"}),
        )
        """);
    getConfiguredTarget("//foo:rule");
    assertNoEvents();
  }

  @Test
  public void selectableDefaultValueWithTypeDefault() throws Exception {
    writeConfigRules();
    scratch.file(
        "srctest/BUILD",
        """
        genrule(
            name = 'gen',
            cmd = '',
            outs = ['gen.out'],
            srcs = select({
                '//conditions:a': None,
            }))
        """);

    useConfiguration("--foo=a");
    ConfiguredTargetAndData ctad = getConfiguredTargetAndData("//srctest:gen");
    AttributeMap attributes = getMapperFromConfiguredTargetAndTarget(ctad);
    assertThat(attributes.get("srcs", LABEL_LIST)).isEmpty();
  }

  @Test
  public void selectableDefaultValueWithRuleDefault() throws Exception {
    writeConfigRules();
    scratch.file(
        "foo/BUILD",
        """
        rule_with_label_default(
            name = 'rule',
            dep = select({
                '//conditions:a': None,
            }))
        rule_with_boolean_attr(
            name = 'default',
            boolean_attr = 1)
        """);

    useConfiguration("--foo=a");
    ConfiguredTargetAndData ctad = getConfiguredTargetAndData("//foo:rule");
    AttributeMap attributes = getMapperFromConfiguredTargetAndTarget(ctad);
    assertThat(attributes.get("dep", BuildType.LABEL))
        .isEqualTo(Label.parseCanonical("//foo:default"));
  }

  @Test
  public void noneValuesWithMultipleSelectsMixedValues() throws Exception {
    writeConfigRules();
    scratch.file(
        "a/BUILD",
        """
        genrule(
            name = 'gen',
            srcs = [],
            outs = ['out'],
            cmd = '',
            message = select({
                '//conditions:a': 'defined message 1',
                '//conditions:b': None,
            }) + select({
                '//conditions:a': None,
                '//conditions:b': 'defined message 2',
            }),
        )
        """);

    reporter.removeHandler(failFastHandler);
    useConfiguration("--define", "mode=a");
    assertThat(getConfiguredTarget("//a:gen")).isNull();
    assertContainsEvent("Cannot combine incompatible types (select of string, select of NoneType)");
  }

  @Test
  public void emptySelectCannotBeConcatenated() throws Exception {
    scratch.file(
        "a/BUILD",
        """
        genrule(
            name = 'gen',
            srcs = [],
            outs = ['out'],
            cmd = select({}) + ' always include'
        )
        """);

    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:gen")).isNull();
    assertContainsEvent(
        "select({}) with an empty dictionary can never resolve because it includes no conditions "
            + "to match");
  }

  @Test
  public void selectOnConstraints() throws Exception {
    // create some useful constraints and platforms.
    scratch.file(
        "conditions/BUILD",
        """
        constraint_setting(name = 'fruit')
        constraint_value(name = 'apple', constraint_setting = 'fruit')
        constraint_value(name = 'banana', constraint_setting = 'fruit')
        platform(
            name = 'apple_platform',
            constraint_values = [':apple'],
        )
        platform(
            name = 'banana_platform',
            constraint_values = [':banana'],
        )
        config_setting(
            name = 'a',
            constraint_values = [':apple']
        )
        config_setting(
            name = 'b',
            constraint_values = [':banana']
        )
        """);
    scratch.file(
        "check/BUILD",
        "filegroup(name = 'adep', srcs = ['afile'])",
        "filegroup(name = 'bdep', srcs = ['bfile'])",
        "filegroup(name = 'defaultdep', srcs = ['defaultfile'])",
        "filegroup(name = 'hello',",
        "    srcs = select({",
        "        '//conditions:a': [':adep'],",
        "        '//conditions:b': [':bdep'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],",
        "    }))");
    checkRule(
        "//check:hello",
        "srcs",
        ImmutableList.of("--experimental_platforms=//conditions:apple_platform"),
        /*expected:*/ ImmutableList.of("src check/afile"),
        /*not expected:*/ ImmutableList.of("src check/bfile", "src check/defaultfile"));
  }

  @Test
  public void selectDirectlyOnConstraints() throws Exception {
    // Tests select()ing directly on a constraint_value (with no intermediate config_setting).
    scratch.file(
        "conditions/BUILD",
        """
        constraint_setting(name = 'fruit')
        constraint_value(name = 'apple', constraint_setting = 'fruit')
        constraint_value(name = 'banana', constraint_setting = 'fruit')
        platform(
            name = 'apple_platform',
            constraint_values = [':apple'],
        )
        platform(
            name = 'banana_platform',
            constraint_values = [':banana'],
        )
        """);
    scratch.file(
        "check/defs.bzl",
        """
        def _impl(ctx):
          pass
        simple_rule = rule(
          implementation = _impl,
          attrs = {'srcs': attr.label_list(allow_files = True)}
        )
        """);
    scratch.file(
        "check/BUILD",
        """
        load('//check:defs.bzl', 'simple_rule')
        filegroup(name = 'adep', srcs = ['afile'])
        filegroup(name = 'bdep', srcs = ['bfile'])
        simple_rule(name = 'hello',
            srcs = select({
                '//conditions:apple': [':adep'],
                '//conditions:banana': [':bdep'],
            }))
        """);
    checkRule(
        "//check:hello",
        "srcs",
        ImmutableList.of("--platforms=//conditions:apple_platform"),
        /*expected:*/ ImmutableList.of("src check/afile"),
        /*not expected:*/ ImmutableList.of("src check/bfile", "src check/defaultfile"));
    checkRule(
        "//check:hello",
        "srcs",
        ImmutableList.of("--platforms=//conditions:banana_platform"),
        /*expected:*/ ImmutableList.of("src check/bfile"),
        /*not expected:*/ ImmutableList.of("src check/afile", "src check/defaultfile"));
  }

  @Test
  public void nonToolchainResolvingTargetsCantSelectDirectlyOnConstraints() throws Exception {
    // Tests select()ing directly on a constraint_value (with no intermediate config_setting).
    scratch.file(
        "conditions/BUILD",
        """
        constraint_setting(name = 'fruit')
        constraint_value(name = 'apple', constraint_setting = 'fruit')
        platform(
            name = 'apple_platform',
            constraint_values = [':apple'],
        )
        """);
    scratch.file(
        "check/BUILD",
        """
        filegroup(name = 'adep', srcs = ['afile'])
        rule_with_no_platform(name = 'hello',
            deps = select({
                '//conditions:apple': [':adep'],
            })
        )
        """);
    reporter.removeHandler(failFastHandler);
    useConfiguration("--platforms=//conditions:apple_platform");
    assertThat(getConfiguredTarget("//check:hello")).isNull();
    assertContainsEvent("//conditions:apple is not a valid select() condition for //check:hello");
  }

  @Test
  public void selectOnlyToolchainResolvingTargetsCanSelectDirectlyOnConstraints() throws Exception {
    // Tests select()ing directly on a constraint_value when the rule uses toolchain resolution
    // *only if it has a select()*. As of this test, alias() is the only rule that supports that
    // (see Alias#useToolchainResolution(ToolchainResolutionMode.ENABLED_ONLY_FOR_COMMON_LOGIC).
    scratch.file(
        "conditions/BUILD",
        """
        constraint_setting(name = 'fruit')
        constraint_value(name = 'apple', constraint_setting = 'fruit')
        constraint_value(name = 'banana', constraint_setting = 'fruit')
        platform(
            name = 'apple_platform',
            constraint_values = [':apple'],
        )
        """);
    scratch.file(
        "check/defs.bzl",
        """
        def _impl(ctx):
          pass
        simple_rule = rule(
          implementation = _impl,
          attrs = {}
        )
        """);
    scratch.file(
        "check/BUILD",
        """
        load('//check:defs.bzl', 'simple_rule')
        filegroup(name = 'bdep', srcs = ['bfile'])
        simple_rule(name = 'hello')
        simple_rule(name = 'tere')
        alias(
            name = 'selectable_alias',
            actual = select({
                '//conditions:apple': ':hello',
                '//conditions:banana': ':tere',
            }))
        """);
    useConfiguration("--platforms=//conditions:apple_platform");
    assertThat(
            getConfiguredTarget("//check:selectable_alias")
                .getActual()
                .getLabel()
                .getCanonicalForm())
        .isEqualTo("//check:hello");
  }

  @Test
  public void multipleMatchErrorWhenAliasResolvesToSameSetting() throws Exception {
    scratch.file(
        "a/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' })
        alias(
            name = 'alias_to_foo',
            actual = ':foo')
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                ':foo': 0,
                'alias_to_foo': 1,
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNull();
    assertContainsEvent(
        "configurable attribute \"boolean_attr\" in //a:binary doesn't match this configuration. "
            + "Would a default condition help?\n\n"
            + "Conditions checked:\n"
            + " //a:foo\n"
            + " //a:alias_to_foo");
  }

  @Test
  public void defaultVisibilityConfigSetting_noVisibilityEnforcement() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=false");
    scratch.file("c/BUILD", "config_setting(name = 'foo', define_values = { 'foo': '1' })");
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void privateVisibilityConfigSetting_noVisibilityEnforcement() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:private']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void publicVisibilityConfigSetting_noVisibilityEnforcement() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:public']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }
  @Test
  public void defaultVisibilityConfigSetting_defaultIsPublic() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    scratch.file("c/BUILD", "config_setting(name = 'foo', define_values = { 'foo': '1' })");
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void privateVisibilityConfigSetting_defaultIsPublic() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:private']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNull();
    assertContainsEvent("'//c:foo' is not visible from\ntarget '//a:binary'");
  }

  @Test
  public void publicVisibilityConfigSetting_defaultIsPublic() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:public']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void defaultPublicVisibility_aliasVisibilityIgnored_aliasVisibilityIsDefault()
      throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions(
        "--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        alias(
            name = 'foo_alias',
            actual = ':foo')
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo_alias': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void defaultPublicVisibility_aliasVisibilityIgnored_aliasVisibilityIsExplicit()
      throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions(
        "--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        alias(
            name = 'foo_alias',
            actual = ':foo',
            # Current flag combo skips this and directly checks the config_setting's visibility.
            visibility = ['//visibility:private']
        )
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo_alias': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void defaultPublicVisibility_aliasVisibilityIgnored_configSettingVisibilityIsExplicit()
      throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions(
        "--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    scratch.file(
        "c/BUILD",
        """
        alias(
            name = 'foo_alias',
            actual = ':foo',
            # Current flag combo skips this and directly checks the config_setting's visibility.
            visibility = ['//visibility:public']
        )
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:private']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo_alias': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNull();
    assertContainsEvent("'//c:foo' is not visible from\ntarget '//a:binary'");
  }

  @Test
  public void defaultPublicVisibility_trimmedConfigsDontCrash() throws Exception {
    // When enforcing config_setting visibility with
    // --incompatible_config_setting_private_default_visibility=false, the alias
    // ConfiguredTargetAndData clones itself with the ConfiguredTargetAndData of the config_setting
    // it refers to. ConfiguredTargetAndData.fromConfiguredTarget has a safety check that both
    // configs are the same. When the target with a select() is a test and --trim_test_configuration
    // is on, the alias takes the parent's config (with TestOptions) but the config_setting has it
    // stripped. This is a regression test that Blaze doesn't crash expecting those configs to be
    // equal.
    setPackageOptions(
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=false");
    useConfiguration("--trim_test_configuration=true");
    scratch.file(
        "c/defs.bzl",
        """
        def _impl(ctx):
            output = ctx.outputs.out
            ctx.actions.write(output = output, content = 'hi', is_executable = True)
            return [DefaultInfo(executable = output)]

        fake_test = rule(
            attrs = {
                'msg': attr.string(),
            },
            test = True,
            outputs = {'out': 'foo.out'},
            implementation = _impl,
        )
        """);
    scratch.file(
        "c/BUILD",
        """
        load(':defs.bzl', 'fake_test')
        alias(
            name = 'foo_alias',
            actual = ':foo',
        )
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
        )
        fake_test(
            name = 'foo_test',
            msg = select({
                ':foo_alias': 'hi',
                '//conditions:default': 'there'
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//c:foo_test")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void defaultVisibilityConfigSetting_defaultIsPrivate() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=true");
    scratch.file("c/BUILD", "config_setting(name = 'foo', define_values = { 'foo': '1' })");
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNull();
    assertContainsEvent("'//c:foo' is not visible from\ntarget '//a:binary'");
  }

  @Test
  public void privateVisibilityConfigSetting_defaultIsPrivate() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=true");
    scratch.file(
        "c/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:private']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNull();
    assertContainsEvent("'//c:foo' is not visible from\ntarget '//a:binary'");
  }

  @Test
  public void publicVisibilityConfigSetting_defaultIsPrivate() throws Exception {
    // Production builds default to private visibility, but BuildViewTestCase defaults to public.
    setPackageOptions("--default_visibility=private",
        "--incompatible_enforce_config_setting_visibility=true",
        "--incompatible_config_setting_private_default_visibility=true");
    scratch.file(
        "c/BUILD",
        """
        config_setting(
            name = 'foo',
            define_values = { 'foo': '1' },
            visibility = ['//visibility:public']
        )
        """);
    scratch.file(
        "a/BUILD",
        """
        rule_with_boolean_attr(
            name = 'binary',
            boolean_attr = select({
                '//c:foo': 0,
                '//conditions:default': 1
            }))
        """);
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//a:binary")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void selectWithLabelKeysInMacro() throws Exception {
    writeConfigRules();
    scratch.file("java/BUILD");
    scratch.file(
        "java/macros.bzl",
        """
        def my_java_binary(name, deps = [], **kwargs):
            native.java_binary(
                name = name,
                deps = select({
                    Label('//conditions:a'): [Label('//java/foo:a')],
                    '//conditions:b': [Label('//java/foo:b')],
                }) + select({
                    '//conditions:a': [Label('//java/foo:a2')],
                    Label('//conditions:b'): [Label('//java/foo:b2')],
                }),
                **kwargs,
            )
        """);
    scratch.file(
        "java/foo/BUILD",
        """
        load('//java:macros.bzl', 'my_java_binary')
        my_java_binary(
            name = 'binary',
            srcs = ['binary.java'],
        )
        java_library(
            name = 'a',
            srcs = ['a.java'])
        java_library(
            name = 'b',
            srcs = ['b.java'])
        java_library(
            name = 'a2',
            srcs = ['a2.java'])
        java_library(
            name = 'b2',
            srcs = ['b2.java'])
        """);

    checkRule(
        "//java/foo:binary",
        "--foo=b",
        /*expected:*/ ImmutableList.of("bin java/foo/libb.jar", "bin java/foo/libb2.jar"),
        /*not expected:*/ ImmutableList.of("bin java/foo/liba.jar", "bin java/foo/liba2.jar"));
  }
}
