// Copyright 2019 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.query2.cquery;

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;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;

import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.TransitionFactories;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.packages.LabelPrinter;
import com.google.devtools.build.lib.packages.RuleTransitionData;
import com.google.devtools.build.lib.query2.PostAnalysisQueryEnvironment;
import com.google.devtools.build.lib.query2.cquery.CqueryOptions.Transitions;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting;
import com.google.devtools.build.lib.query2.engine.QueryExpression;
import com.google.devtools.build.lib.query2.engine.QueryParser;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for the transitions output format. */
@RunWith(JUnit4.class)
public class TransitionsOutputFormatterTest extends ConfiguredTargetQueryTest {

  private CqueryOptions options;
  private Reporter reporter;
  private final List<Event> events = new ArrayList<>();
  private ConfiguredRuleClassProvider ruleClassProvider;

  @Before
  public final void setUpCqueryOptions() {
    this.options = new CqueryOptions();
    helper.setQuerySettings(Setting.INCLUDE_ASPECTS);
    this.reporter = new Reporter(new EventBus(), events::add);
  }

  @Test
  public void testTransitions_full() throws Exception {
    setUpRules();

    writeFile(
        "test/BUILD",
        "my_rule(name = 'rule_with_patch',",
        "  patched = [':foo', ':foo2', ':trimmed_foo'],",
        ")",
        "my_rule(name = 'rule_with_split',",
        "  split = ':bar',",
        ")",
        "simple_rule(name = 'foo')",
        "simple_rule(name = 'foo2')",
        "simple_rule(name = 'trimmed_foo')",
        "simple_rule(name = 'bar')");

    List<String> result = getOutput("deps(//test:rule_with_patch)", Transitions.FULL);

    assertThat(result.get(0)).startsWith("FooPatchTransition -> //test:rule_with_patch");
    assertThat(result.get(1)).startsWith("  patched#//test:foo#FooPatch");
    assertThat(result.get(2)).isEqualTo("    foo:SET BY RULE CLASS PATCH -> [SET BY PATCH]");
    assertThat(result.get(3)).startsWith("  patched#//test:foo2#FooPatch");
    assertThat(result.get(4)).isEqualTo(result.get(2));
    assertThat(result.get(5))
        .startsWith("  patched#//test:trimmed_foo#(FooPatchTransition + FooPatchTransition(trim))");
    assertThat(result.get(6)).isEqualTo("    foo:SET BY RULE CLASS PATCH -> [SET BY TRIM]");

    result = getOutput("deps(//test:rule_with_split)", Transitions.FULL);
    assertThat(result.get(1)).startsWith("  split#//test:bar#FooSplitTransition");
    // TODO(shahan): the right hand side of the diff below is in split dep ordering, which is
    // dependent on checksum values. It could be brittle.
    assertThat(result.get(2))
        .isEqualTo("    foo:SET BY RULE CLASS PATCH -> [SET BY SPLIT 2, SET BY SPLIT 1]");
  }

  @Test
  public void testTransitions_lite() throws Exception {
    setUpRules();

    writeFile(
        "test/BUILD",
        "my_rule(name = 'rule_with_patch',",
        "  patched = [':foo', ':foo2'],",
        ")",
        "my_rule(name = 'rule_with_split',",
        "  split = ':bar',",
        ")",
        "simple_rule(name = 'foo')",
        "simple_rule(name = 'foo2')",
        "simple_rule(name = 'bar')");

    List<String> result = getOutput("deps(//test:rule_with_patch)", Transitions.LITE);

    assertThat(result.get(0)).startsWith("FooPatchTransition -> //test:rule_with_patch");
    assertThat(result.get(1)).startsWith("  patched#//test:foo#FooPatchTransition");
    assertThat(result.get(2)).startsWith("  patched#//test:foo2#FooPatchTransition");

    result = getOutput("deps(//test:rule_with_split)", Transitions.LITE);
    assertThat(result.get(0)).startsWith("FooPatchTransition -> //test:rule_with_split");
    assertThat(result.get(1)).startsWith("  split#//test:bar#FooSplitTransition");
  }

  @Test
  public void testTransitions_getRightConfigurations() throws Exception {
    setUpRules();

    writeFile(
        "test/BUILD",
        "my_rule(name = 'rule_with_patch',",
        "  patched = [':foo'],",
        ")",
        "simple_rule(name = 'foo')");

    List<String> result = getOutput("deps(//test:rule_with_patch)", Transitions.LITE);
    String depEntry = result.get(2);
    // depEntry is "//test:rule_with_path (<config_id>)". This gets just "<config_id>".
    String postPatchConfig =
        depEntry.substring(depEntry.lastIndexOf("(") + 1, depEntry.length() - 1);
    assertThat(result.get(1)).endsWith(postPatchConfig);
  }

  @Test
  public void testTransitions_noTransitions() throws Exception {
    setUpRules();
    writeFile(
        "test/BUILD",
        "simple_rule(name = 'foo')");

    List<String> result = getOutput("//test:foo", Transitions.NONE);
    assertThat(result).isEmpty();
    assertThat(events).hasSize(1);
    assertThat(events.get(0).getMessage())
        .isEqualTo(
            "Instead of using --output=transitions, set the --transitions flag explicitly to 'lite'"
                + " or 'full'");
  }

  @Test
  public void nonAttributeDependencySkipped() throws Exception {
    setUpRules();

    // A visibility dependency on a package_group produces a
    // DependencyKind.NonAttributeDependencyKind. This test checks that the existence of those
    // attribute types doesn't crash cquery.

    writeFile(
        "test/BUILD",
        "package_group(",
        "    name = 'custom_visibility',",
        "    packages = ['//test/...'],",
        ")",
        "simple_rule(",
        "    name = 'child',",
        ")",
        "simple_rule(",
        "    name = 'parent',",
        "    deps = [':child'],",
        "    visibility = [':custom_visibility'],",
        ")");

    assertThat(getOutput("deps(//test:parent)", Transitions.LITE)).isNotNull();
    assertThat(events).isEmpty();
  }

  private void setUpRules() throws Exception {
    TransitionFactory<RuleTransitionData> infixTrimmingTransitionFactory =
        (ruleData) -> {
          if (!ruleData.rule().getName().contains("trimmed")) {
            return NoTransition.INSTANCE;
          }
          // rename the transition so it's distinguishable from the others in tests
          return new FooPatchTransition("SET BY TRIM", "FooPatchTransition(trim)");
        };
    FooPatchTransition ruleClassTransition = new FooPatchTransition("SET BY RULE CLASS PATCH");
    FooPatchTransition attributePatchTransition = new FooPatchTransition("SET BY PATCH");
    FooSplitTransition attributeSplitTransitions =
        new FooSplitTransition("SET BY SPLIT 1", "SET BY SPLIT 2");

    MockRule ruleWithTransitions =
        () ->
            MockRule.define(
                "my_rule",
                (builder, env) ->
                    builder
                        .cfg(unused -> ruleClassTransition)
                        .add(
                            attr("patched", LABEL_LIST)
                                .allowedFileTypes(FileTypeSet.ANY_FILE)
                                .cfg(TransitionFactories.of(attributePatchTransition)))
                        .add(
                            attr("split", LABEL)
                                .allowedFileTypes(FileTypeSet.ANY_FILE)
                                .cfg(TransitionFactories.of(attributeSplitTransitions))));
    MockRule simpleRule =
        () ->
            MockRule.define(
                "simple_rule",
                (builder, env) ->
                    builder
                        .add(attr("deps", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)));

    this.ruleClassProvider =
        setRuleClassProviders(ruleWithTransitions, simpleRule)
            .overrideTrimmingTransitionFactoryForTesting(infixTrimmingTransitionFactory)
            .build();
    helper.useRuleClassProvider(ruleClassProvider);
  }

  private List<String> getOutput(String queryExpression, CqueryOptions.Transitions verbosity)
      throws Exception {
    QueryExpression expression = QueryParser.parse(queryExpression, getDefaultFunctions());
    Set<String> targetPatternSet = new LinkedHashSet<>();
    expression.collectTargetPatterns(targetPatternSet);
    helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);
    PostAnalysisQueryEnvironment<ConfiguredTarget> env =
        ((ConfiguredTargetQueryHelper) helper).getPostAnalysisQueryEnvironment(targetPatternSet);
    options.transitions = verbosity;
    // TODO(blaze-configurability): Test late-bound attributes.
    TransitionsOutputFormatterCallback callback =
        new TransitionsOutputFormatterCallback(
            reporter,
            options,
            /* out= */ null,
            getHelper().getSkyframeExecutor(),
            env.getAccessor(),
            ruleClassProvider,
            LabelPrinter.legacy());
    env.evaluateQuery(env.transformParsedQuery(QueryParser.parse(queryExpression, env)), callback);
    return callback.getResult();
  }
}
