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

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.syntax.Type.STRING;

import com.google.common.base.Joiner;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.testutil.UnknownRuleConfiguredTarget;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link AggregatingAttributeMapper}.
 */
@RunWith(JUnit4.class)
public class AggregatingAttributeMapperTest extends AbstractAttributeMapperTest {

  @Before
  public final void createMapper() throws Exception {
    // Run AbstractAttributeMapper tests through an AggregatingAttributeMapper.
    mapper = AggregatingAttributeMapper.of(rule);
  }

  private static Label getDefaultMallocLabel(Rule rule) {
    return Verify.verifyNotNull(
        (Label) rule.getRuleClassObject().getAttributeByName("malloc").getDefaultValueUnchecked());
  }

  /**
   * Tests that {@link AggregatingAttributeMapper#visitAttribute} returns an
   * attribute's sole value when declared directly (i.e. not as a configurable dict).
   */
  @Test
  public void testGetPossibleValuesDirectAttribute() throws Exception {
    Rule rule = scratchRule("a", "myrule",
        "sh_binary(name = 'myrule',",
        "          srcs = ['a.sh'])");
    assertThat(AggregatingAttributeMapper.of(rule).visitAttribute("srcs", BuildType.LABEL_LIST))
        .containsExactly(ImmutableList.of(Label.create("@//a", "a.sh")));
  }

  /**
   * Tests that {@link AggregatingAttributeMapper#visitAttribute} returns
   * every possible value that a configurable attribute can resolve to.
   */
  @Test
  public void testGetPossibleValuesConfigurableAttribute() throws Exception {
    Rule rule = scratchRule("a", "myrule",
        "sh_binary(name = 'myrule',",
        "          srcs = select({",
        "              '//conditions:a': ['a.sh'],",
        "              '//conditions:b': ['b.sh'],",
        "              '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': ['default.sh'],",
        "          }))");
    assertThat(AggregatingAttributeMapper.of(rule).visitAttribute("srcs", BuildType.LABEL_LIST))
        .containsExactly(
            ImmutableList.of(Label.create("@//a", "a.sh")),
            ImmutableList.of(Label.create("@//a", "b.sh")),
            ImmutableList.of(Label.create("@//a", "default.sh")));
  }

  @Test
  public void testGetPossibleValuesWithConcatenatedSelects() throws Exception {
    Rule rule = scratchRule("a", "myrule",
        "sh_binary(name = 'myrule',",
        "          srcs = select({",
        "                  '//conditions:a1': ['a1.sh'],",
        "                  '//conditions:b1': ['b1.sh']})",
        "              + select({",
        "                  '//conditions:a2': ['a2.sh'],",
        "                  '//conditions:b2': ['b2.sh']})",
        "          )");
    assertThat(AggregatingAttributeMapper.of(rule).visitAttribute("srcs", BuildType.LABEL_LIST))
        .containsExactly(
            ImmutableList.of(Label.create("@//a", "a1.sh"), Label.create("@//a", "a2.sh")),
            ImmutableList.of(Label.create("@//a", "a1.sh"), Label.create("@//a", "b2.sh")),
            ImmutableList.of(Label.create("@//a", "b1.sh"), Label.create("@//a", "a2.sh")),
            ImmutableList.of(Label.create("@//a", "b1.sh"), Label.create("@//a", "b2.sh")));
  }

  /**
   * Given a large number of selects, we expect better than the naive
   * exponential performance from evaluating select1 x select2 x select3 x ...
   */
  @Test
  public void testGetPossibleValuesWithManySelects() throws Exception {
    String pattern = " + select({'//conditions:a1': '%c', '//conditions:a2': '%s'})";
    StringBuilder ruleDef = new StringBuilder();
    ruleDef.append("genrule(name = 'gen', srcs = [], outs = ['gen.out'], cmd = ''");
    for (char c : "abcdefghijklmnopqrstuvwxyz".toCharArray()) {
      ruleDef.append(String.format(pattern, c, Character.toUpperCase(c)));
    }
    ruleDef.append(")");
    Rule rule = scratchRule("a", "gen", ruleDef.toString());
    // Naive evaluation would visit 2^26 cases and either overflow memory or timeout the test.
    assertThat(AggregatingAttributeMapper.of(rule).visitAttribute("cmd", Type.STRING))
        .containsExactly("abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  }

  /**
   * Tests that, on rule visitation, {@link AggregatingAttributeMapper} visits *every* possible
   * value in a configurable attribute (including configuration key labels).
   */
  @Test
  public void testVisitationConfigurableAttribute() throws Exception {
    Rule rule = scratchRule("a", "myrule",
        "sh_binary(name = 'myrule',",
        "          srcs = select({",
        "              '//conditions:a': ['a.sh'],",
        "              '//conditions:b': ['b.sh'],",
        "              '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': ['default.sh'],",
        "          }))");

    assertThat(getLabelsForAttribute(AggregatingAttributeMapper.of(rule), "srcs"))
        .containsExactlyElementsIn(
            ImmutableList.of(
                "//a:a.sh", "//a:b.sh", "//a:default.sh", "//conditions:a", "//conditions:b"));
  }

  @Test
  public void testVisitationWithDefaultValues() throws Exception {
    Rule rule = scratchRule("a", "myrule",
        "cc_binary(name = 'myrule',",
        "    srcs = [],",
        "    malloc = select({",
        "        '//conditions:a': None,",
        "    }))");

    assertThat(getLabelsForAttribute(AggregatingAttributeMapper.of(rule), "malloc"))
        .containsExactly("//conditions:a", getDefaultMallocLabel(rule).toString());
  }


  @Test
  public void testGetReachableLabels() throws Exception {
    Rule rule = scratchRule("x", "main",
        "cc_binary(",
        "    name = 'main',",
        "    srcs = select({",
        "        '//conditions:a': ['a.cc'],",
        "        '//conditions:b': ['b.cc']})",
        "    + ",
        "        ['always.cc']",
        "    + ",
        "         select({",
        "        '//conditions:c': ['c.cc'],",
        "        '//conditions:d': ['d.cc'],",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': ['default.cc'],",
        "    }))");

    ImmutableList<Label> valueLabels = ImmutableList.of(
        Label.create("@//x", "a.cc"), Label.create("@//x", "b.cc"),
        Label.create("@//x", "always.cc"), Label.create("@//x", "c.cc"),
        Label.create("@//x", "d.cc"), Label.create("@//x", "default.cc"));
    ImmutableList<Label> keyLabels = ImmutableList.of(
        Label.create("@//conditions", "a"), Label.create("@//conditions", "b"),
        Label.create("@//conditions", "c"), Label.create("@//conditions", "d"));

    AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
    assertThat(mapper.getReachableLabels("srcs", true))
        .containsExactlyElementsIn(Iterables.concat(valueLabels, keyLabels));
    assertThat(mapper.getReachableLabels("srcs", false)).containsExactlyElementsIn(valueLabels);
  }

  @Test
  public void testGetReachableLabelsWithDefaultValues() throws Exception {
    Rule rule = scratchRule("a", "myrule",
        "cc_binary(name = 'myrule',",
        "    srcs = [],",
        "    malloc = select({",
        "        '//conditions:a': None,",
        "    }))");

    AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
    assertThat(mapper.getReachableLabels("malloc", true))
        .containsExactly(
            getDefaultMallocLabel(rule), Label.create("@//conditions", "a"));
  }

  @Test
  public void testDuplicateCheckOnNullValues() throws Exception {
    if (getAnalysisMock().isThisBazel()) {
      return;
    }
    Rule rule = scratchRule("x", "main",
        "java_binary(",
        "    name = 'main',",
        "    srcs = ['main.java'])");
    AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
    Attribute launcherAttribute = mapper.getAttributeDefinition("launcher");
    assertThat(mapper.get(launcherAttribute.getName(), launcherAttribute.getType())).isNull();
    assertThat(mapper.checkForDuplicateLabels(launcherAttribute)).isEmpty();
  }

  /**
   * Custom rule to support testing over computed defaults.
   */
  public static final class RuleWithComputedDefaults
      implements RuleDefinition, RuleConfiguredTargetFactory {
    @Override
    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
      return builder
          .add(attr("configurable1", STRING))
          .add(attr("configurable2", STRING))
          .add(attr("nonconfigurable", STRING).nonconfigurable("that's the point"))
          .add(attr("$computed_default_with_configurable_deps", STRING).value(
              new Attribute.ComputedDefault("configurable1", "configurable2") {
                @Override
                public Object getDefault(AttributeMap rule) {
                  return Joiner.on(" ").join(
                      rule.get("configurable1", STRING),
                      rule.get("configurable2", STRING),
                      rule.get("nonconfigurable", STRING)
                  );
                }
              }))
          .add(attr("$computed_default_without_configurable_deps", STRING).value(
              new Attribute.ComputedDefault() {
                @Override
                public Object getDefault(AttributeMap rule) {
                  return rule.get("nonconfigurable", STRING);
                }
              }))
          .build();
    }

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

    @Override
    public ConfiguredTarget create(RuleContext ruleContext) {
      throw new UnsupportedOperationException();
    }
  }

  @Override
  protected ConfiguredRuleClassProvider getRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder =
        new ConfiguredRuleClassProvider.Builder()
            .addRuleDefinition(new RuleWithComputedDefaults());
    TestRuleClassProvider.addStandardRules(builder);
    return builder.build();
  }

  @Test
  public void testComputedDefaultWithConfigurableDeps() throws Exception {
    Rule rule = scratchRule("x", "bb",
        "rule_with_computed_defaults(",
        "    name = 'bb',",
        "    configurable1 = select({':a': 'of', ':b': 'from'}),",
        "    configurable2 = select({':a': 'this', ':b': 'the'}),",
        "    nonconfigurable = 'bottom')");
    assertThat(AggregatingAttributeMapper.of(rule)
        .visitAttribute("$computed_default_with_configurable_deps", STRING))
        .containsExactly("of this bottom", "from this bottom", "of the bottom", "from the bottom");
  }

  @Test
  public void testComputedDefaultWithoutConfigurableDeps() throws Exception {
    Rule rule = scratchRule("x", "bb",
        "rule_with_computed_defaults(",
        "    name = 'bb',",
        "    nonconfigurable = 'swim up')");
    assertThat(AggregatingAttributeMapper.of(rule)
        .visitAttribute("$computed_default_without_configurable_deps", STRING))
        .containsExactly("swim up");
  }

}
