// 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.*"));
  }
}
