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

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

import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link ConfiguredAttributeMapper}.
 *
 * <p>This is distinct from {@link
 * com.google.devtools.build.lib.analysis.select.ConfiguredAttributeMapperCommonTest} because the
 * latter needs to inherit from {@link
 * com.google.devtools.build.lib.analysis.select.AbstractAttributeMapperTest} to run tests common to
 * all attribute mappers.
 */
@RunWith(JUnit4.class)
public class ConfiguredAttributeMapperTest extends BuildViewTestCase {

  /**
   * Returns a ConfiguredAttributeMapper bound to the given rule with the target configuration.
   */
  private ConfiguredAttributeMapper getMapper(String label) throws Exception {
    ConfiguredTargetAndData ctad = getConfiguredTargetAndData(label);
    return getMapperFromConfiguredTargetAndTarget(ctad);
  }

  private void writeConfigRules() throws Exception {
    scratch.file(
        "conditions/BUILD",
        """
        config_setting(
            name = "a",
            values = {"define": "mode=a"},
        )

        config_setting(
            name = "b",
            values = {"define": "mode=b"},
        )
        """);
  }

  /**
   * Tests that {@link ConfiguredAttributeMapper#get} only gets the configuration-appropriate
   * value.
   */
  @Test
  public void testGetAttribute() throws Exception {
    writeConfigRules();
    scratch.file("a/BUILD",
        "genrule(",
        "    name = 'gen',",
        "    srcs = [],",
        "    outs = ['out'],",
        "    cmd = select({",
        "        '//conditions:a': 'a command',",
        "        '//conditions:b': 'b command',",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': 'default command',",
        "    }))");

    useConfiguration("--define", "mode=a");
    assertThat(getMapper("//a:gen").get("cmd", Type.STRING)).isEqualTo("a command");

    useConfiguration("--define", "mode=b");
    assertThat(getMapper("//a:gen").get("cmd", Type.STRING)).isEqualTo("b command");

    useConfiguration("--define", "mode=c");
    assertThat(getMapper("//a:gen").get("cmd", Type.STRING)).isEqualTo("default command");
  }

  /**
   * Tests that label visitation only travels down configuration-appropriate paths.
   */
  @Test
  public void testLabelVisitation() throws Exception {
    writeConfigRules();
    scratch.file("a/BUILD",
        "sh_binary(",
        "    name = 'bin',",
        "    srcs = ['bin.sh'],",
        "    deps = select({",
        "        '//conditions:a': [':adep'],",
        "        '//conditions:b': [':bdep'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],",
        "    }))",
        "sh_library(",
        "    name = 'adep',",
        "    srcs = ['adep.sh'])",
        "sh_library(",
        "    name = 'bdep',",
        "    srcs = ['bdep.sh'])",
        "sh_library(",
        "    name = 'defaultdep',",
        "    srcs = ['defaultdep.sh'])");

    List<Label> visitedLabels = new ArrayList<>();
    Label binSrc = Label.parseCanonical("//a:bin.sh");

    useConfiguration("--define", "mode=a");
    addRelevantLabels(getMapper("//a:bin"), visitedLabels);
    assertThat(visitedLabels).containsExactly(binSrc, Label.parseCanonical("//a:adep"));

    visitedLabels.clear();
    useConfiguration("--define", "mode=b");
    addRelevantLabels(getMapper("//a:bin"), visitedLabels);
    assertThat(visitedLabels).containsExactly(binSrc, Label.parseCanonical("//a:bdep"));

    visitedLabels.clear();
    useConfiguration("--define", "mode=c");
    addRelevantLabels(getMapper("//a:bin"), visitedLabels);
    assertThat(visitedLabels).containsExactly(binSrc, Label.parseCanonical("//a:defaultdep"));
  }

  private static void addRelevantLabels(
      ConfiguredAttributeMapper mapper, List<Label> visitedLabels) {
    mapper.visitAllLabels(
        (attribute, label) -> {
          if (label.getPackageIdentifier().getPackageFragment().toString().equals("a")) {
            visitedLabels.add(label);
          }
        });
  }

  /**
   * Tests that for configurable attributes where the *values* are evaluated in different
   * configurations, the configuration checking still uses the original configuration.
   */
  @Test
  public void testConfigurationTransitions() throws Exception {
    writeConfigRules();
    scratch.file("a/BUILD",
        "genrule(",
        "    name = 'gen',",
        "    srcs = [],",
        "    outs = ['out'],",
        "    cmd = 'nothing',",
        "    tools = select({",
        "        '//conditions:a': [':adep'],",
        "        '//conditions:b': [':bdep'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],",
        "    }))",
        "sh_binary(",
        "    name = 'adep',",
        "    srcs = ['adep.sh'])",
        "sh_binary(",
        "    name = 'bdep',",
        "    srcs = ['bdep.sh'])",
        "sh_binary(",
        "    name = 'defaultdep',",
        "    srcs = ['defaultdep.sh'])");
    useConfiguration("--define", "mode=b");

    // Target configuration is in dbg mode, so we should match //conditions:b:
    assertThat(getMapper("//a:gen").get("tools", BuildType.LABEL_LIST))
        .containsExactly(Label.parseCanonical("//a:bdep"));

    // Verify the "tools" dep uses a different configuration that's not also in "dbg":
    assertThat(
            getTarget("//a:gen")
                .getAssociatedRule()
                .getRuleClassObject()
                .getAttributeByName("tools")
                .getTransitionFactory()
                .isTool())
        .isTrue();
    assertThat(getExecConfiguration().getCompilationMode()).isEqualTo(CompilationMode.OPT);
  }

  @Test
  public void testConcatenatedSelects() throws Exception {
    scratch.file(
        "hello/BUILD",
        """
        config_setting(
            name = "a",
            values = {"define": "foo=a"},
        )

        config_setting(
            name = "b",
            values = {"define": "foo=b"},
        )

        config_setting(
            name = "c",
            values = {"define": "bar=c"},
        )

        config_setting(
            name = "d",
            values = {"define": "bar=d"},
        )

        genrule(
            name = "gen",
            srcs = select({
                       ":a": ["a.in"],
                       ":b": ["b.in"],
                   }) +
                   select({
                       ":c": ["c.in"],
                       ":d": ["d.in"],
                   }),
            outs = ["out"],
            cmd = "nothing",
        )
        """);
    useConfiguration("--define", "foo=a", "--define", "bar=d");
    assertThat(getMapper("//hello:gen").get("srcs", BuildType.LABEL_LIST))
        .containsExactly(
            Label.parseCanonical("//hello:a.in"), Label.parseCanonical("//hello:d.in"));
  }

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

    useConfiguration("--define", "mode=a");
    assertThat(getMapper("//a:gen").isAttributeValueExplicitlySpecified("message")).isTrue();

    useConfiguration("--define", "mode=b");
    assertThat(getMapper("//a:gen").isAttributeValueExplicitlySpecified("message")).isFalse();
  }

  @Test
  public void testNoneValuesWithMultipleSelectsAllNone() 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": "defined message 2",
                "//conditions:b": None,
            }),
        )
        """);

    useConfiguration("--define", "mode=a");
    assertThat(getMapper("//a:gen").isAttributeValueExplicitlySpecified("message")).isTrue();

    useConfiguration("--define", "mode=b");
    assertThat(getMapper("//a:gen").isAttributeValueExplicitlySpecified("message")).isFalse();
  }

  @Test
  public void testNoneValueOnDefaultConditionWithNullDefault() throws Exception {
    writeConfigRules();
    scratch.file("a/BUILD",
        "cc_library(",
        "    name = 'lib',",
        "    srcs = ['lib.cc'],",
        "    linkstamp = select({",
        "        '//conditions:a': 'notused_linkstamp.cc',",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': None,",
        "    }),",
        ")");

    useConfiguration();
    assertThat(getMapper("//a:lib").isAttributeValueExplicitlySpecified("linkstamp")).isFalse();
    assertThat(getMapper("//a:lib").get("linkstamp", BuildType.LABEL)).isNull();
  }

  @Test
  public void testNoneValueOnMandatoryAttribute() throws Exception {
    scratch.file("a/BUILD", "alias(name='a', actual=select({'//conditions:default': None}))");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//a:a");
    assertContainsEvent("Mandatory attribute 'actual' resolved to 'None'");
  }

  @Test
  public void testAliasedConfigSetting() throws Exception {
    writeConfigRules();
    scratch.file(
        "a/BUILD",
        """
        alias(
            name = "aliased_a",
            actual = "//conditions:a",
        )

        genrule(
            name = "gen",
            srcs = [],
            outs = ["out"],
            cmd = "",
            message = select({
                ":aliased_a": "defined message",
                "//conditions:default": None,
            }),
        )
        """);
    useConfiguration("--define", "mode=a");
    assertThat(getMapper("//a:gen").get("message", Type.STRING)).isEqualTo("defined message");
  }

  @Test
  public void noMatchErrorFormat() throws Exception {
    scratch.file(
        "a/BUILD",
        """
        config_setting(
            name = "a",
            values = {"define": "mode=a"},
        )

        config_setting(
            name = "b",
            values = {"define": "mode=b"},
        )

        genrule(
            name = "g",
            srcs = [],
            outs = ["out"],
            cmd = "",
            message = select({
                ":a": "not chosen",
                ":b": "not chosen",
            }),
        )
        """);
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//a:g");
    // Match with a regex pattern because the error message includes the failing target's
    // configuration ID, which can vary among builds.
    assertContainsEvent(
        Pattern.compile(
            ".*configurable attribute \"message\" in //a:g doesn't match this configuration. Would"
                + " a default condition help\\?\n"
                + "\n"
                + "Conditions checked:\n"
                + " //a:a\n"
                + " //a:b\n"
                + "\n"
                + "To see a condition's definition, run: bazel query --output=build <condition"
                + " label>.\n"
                + "\n"
                + "This instance of //a:g has configuration identifier .*. To inspect its"
                + " configuration, run: bazel config .*.\n"
                + "\n"
                + "For more help, see"
                + " https://bazel.build/docs/configurable-attributes"
                + "#faq-select-choose-condition.*"));
  }
}
