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

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 com.google.common.collect.Iterables;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.analysis.AnalysisProtos;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.TransitionFactories;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.query2.ProtoOutputFormatterCallback.OutputType;
import com.google.devtools.build.lib.query2.engine.ConfiguredTargetQueryHelper;
import com.google.devtools.build.lib.query2.engine.ConfiguredTargetQueryTest;
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.query2.output.AspectResolver.Mode;
import com.google.devtools.build.lib.query2.output.CqueryOptions;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;

/**
 * Test for cquery's proto output format.
 *
 * <p>TODO(juliexxia): refactor all cquery output format tests to consolidate duplicate
 * infrastructure.
 */
public class ProtoOutputFormatterCallbackTest extends ConfiguredTargetQueryTest {

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

  @Before
  public final void setUpCqueryOptions() {
    this.options = new CqueryOptions();
    options.aspectDeps = Mode.OFF;
    options.protoIncludeConfigurations = true;

    this.reporter = new Reporter(new EventBus(), events::add);
  }

  @Test
  public void testSelectInAttribute() throws Exception {
    MockRule depsRule =
        () ->
            MockRule.define(
                "my_rule",
                (builder, env) ->
                    builder
                        .add(attr("deps", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)));
    helper.useRuleClassProvider(setRuleClassProviders(depsRule).build());

    writeFile(
        "test/BUILD",
        "my_rule(name = 'my_rule',",
        "  deps = select({",
        "    ':garfield': ['lasagna.java', 'naps.java'],",
        "    '//conditions:default': ['mondays.java']",
        "  })",
        ")",
        "config_setting(",
        "  name = 'garfield',",
        "  values = {'test_arg': 'cat'}",
        ")");

    AnalysisProtos.ConfiguredTarget myRuleProto =
        (Iterables.getOnlyElement(getOutput("//test:my_rule").getResultsList()));
    List<Build.Attribute> attributes = myRuleProto.getTarget().getRule().getAttributeList();
    for (Build.Attribute attribute : attributes) {
      if (!attribute.getName().equals("deps")) {
        continue;
      }
      assertThat(attribute.getStringListValueCount()).isEqualTo(1);
      assertThat(attribute.getStringListValue(0)).isEqualTo("//test:mondays.java");
      break;
    }

    getHelper().useConfiguration("--test_arg=cat");
    myRuleProto = Iterables.getOnlyElement(getOutput("//test:my_rule").getResultsList());
    attributes = myRuleProto.getTarget().getRule().getAttributeList();
    for (Build.Attribute attribute : attributes) {
      if (!attribute.getName().equals("deps")) {
        continue;
      }
      assertThat(attribute.getStringListValueCount()).isEqualTo(2);
      assertThat(attribute.getStringListValue(0)).isEqualTo("//test:lasagna.java");
      assertThat(attribute.getStringListValue(1)).isEqualTo("//test:naps.java");
      break;
    }
  }

  @Test
  public void testConfigurationHash() throws Exception {
    TestArgPatchTransition attributePatchTransition = new TestArgPatchTransition("SET BY PATCH");

    MockRule ruleWithPatch =
        () ->
            MockRule.define(
                "my_rule",
                (builder, env) ->
                    builder.add(
                        attr("deps", LABEL_LIST)
                            .allowedFileTypes(FileTypeSet.ANY_FILE)
                            .cfg(TransitionFactories.of(attributePatchTransition))));

    helper.useRuleClassProvider(setRuleClassProviders(ruleWithPatch, getSimpleRule()).build());

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

    // Assert checksum from proto is proper checksum.
    AnalysisProtos.ConfiguredTarget myRuleProto =
        Iterables.getOnlyElement(getOutput("//test:my_rule").getResultsList());
    ConfiguredTarget myRule = Iterables.getOnlyElement(eval("//test:my_rule"));

    assertThat(myRuleProto.getConfiguration().getChecksum())
        .isEqualTo(myRule.getConfigurationChecksum());

    // Assert checksum for two configured targets in proto are not the same.
    List<AnalysisProtos.ConfiguredTarget> protoDeps =
        getOutput("deps(//test:my_rule)").getResultsList();
    assertThat(protoDeps).hasSize(2);

    Iterator<AnalysisProtos.ConfiguredTarget> protoDepsIterator = protoDeps.iterator();
    assertThat(protoDepsIterator.next().getConfiguration().getChecksum())
        .isNotEqualTo(protoDepsIterator.next().getConfiguration().getChecksum());
  }

  @Test
  public void testAlias() throws Exception {
    helper.useRuleClassProvider(setRuleClassProviders(getSimpleRule()).build());
    writeFile(
        "test/BUILD",
        "simple_rule(name = 'my_rule')",
        "alias(name = 'my_alias', actual = ':my_rule')");

    AnalysisProtos.ConfiguredTarget alias =
        Iterables.getOnlyElement(getOutput("//test:my_alias").getResultsList());

    assertThat(alias.getTarget().getRule().getName()).isEqualTo("//test:my_alias");
    assertThat(alias.getTarget().getRule().getRuleInputCount()).isEqualTo(1);
    assertThat(alias.getTarget().getRule().getRuleInput(0)).isEqualTo("//test:my_rule");
  }

  /* See b/209787345 for context. */
  @Test
  public void testAlias_withSelect() throws Exception {
    helper.useRuleClassProvider(setRuleClassProviders(getSimpleRule()).build());
    writeFile(
        "test/BUILD",
        "alias(",
        "  name = 'my_alias_rule',",
        "  actual = select({",
        "    ':config1': ':target1',",
        "    '//conditions:default': ':target2',",
        "  }),",
        ")",
        "config_setting(",
        "  name = 'config1',",
        "  values = {'test_arg': 'woof'},",
        ")",
        "simple_rule(name = 'target1')",
        "simple_rule(name = 'target2')");
    getHelper().useConfiguration("--test_arg=woof");
    helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);

    List<AnalysisProtos.ConfiguredTarget> myAliasRuleProto =
        getOutput("deps(//test:my_alias_rule)").getResultsList();

    List<String> depNames = new ArrayList<>(myAliasRuleProto.size());
    myAliasRuleProto.forEach(
        configuredTarget -> depNames.add(configuredTarget.getTarget().getRule().getName()));
    assertThat(depNames)
        .containsExactly("//test:my_alias_rule", "//test:config1", "//test:target1");
  }

  private MockRule getSimpleRule() {
    return () -> MockRule.define("simple_rule");
  }

  private AnalysisProtos.CqueryResult getOutput(String queryExpression) 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);

    ProtoOutputFormatterCallback callback =
        new ProtoOutputFormatterCallback(
            reporter,
            options,
            /*out=*/ null,
            getHelper().getSkyframeExecutor(),
            env.getAccessor(),
            options.aspectDeps.createResolver(
                getHelper().getPackageManager(), NullEventHandler.INSTANCE),
            OutputType.BINARY);
    env.evaluateQuery(expression, callback);
    return callback.getProtoResult();
  }
}
