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

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.testutil.TestConstants.PLATFORM_LABEL;

import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.test.TestConfiguration.TestOptions;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.query2.PostAnalysisQueryEnvironment;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction;
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.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/** Tests for {@link PostAnalysisQueryEnvironment}. */
public abstract class PostAnalysisQueryTest<T> extends AbstractQueryTest<T> {

  // Also filter out platform dependencies.
  @Override
  protected String getDependencyCorrection() {
    return " - deps(" + PLATFORM_LABEL + ")";
  }

  static final String DEFAULT_UNIVERSE = "DEFAULT_UNIVERSE";

  @Before
  public final void disableOrderedResults() {
    helper.setOrderedResults(false);
  }

  @Before
  public final void setMockToolsConfig() {
    this.mockToolsConfig = getHelper().getMockToolsConfig();
  }

  /**
   * In production, cquery constructs the universe by parsing targets from the query expression and
   * building them at the top level. If this is not viable (e.g. component functions) or not desired
   * (e.g. somepath(//foo-built-in-target, //bar-built-in-host), the user must specify the
   * --universe_scope flag. Enforce the same behavior in this test by initializing universe scope to
   * an invalid target expression.
   */
  @Override
  protected String getDefaultUniverseScope() {
    return DEFAULT_UNIVERSE;
  }

  protected PostAnalysisQueryHelper<T> getHelper() {
    return (PostAnalysisQueryHelper<T>) helper;
  }

  /**
   * At the end of each eval, reset the universe scope to the default if the test doesn't use a
   * single universe scope.
   */
  @Override
  protected Set<T> eval(String query) throws Exception {
    maybeParseUniverseScope(query);
    Set<T> queryResult = super.eval(query);
    if (!getHelper().isWholeTestUniverse()) {
      helper.setUniverseScope(getDefaultUniverseScope());
    }
    return queryResult;
  }

  @Override
  protected String evalThrows(String query, boolean unconditionallyThrows) throws Exception {
    maybeParseUniverseScope(query);
    String queryResult = super.evalThrows(query, unconditionallyThrows);
    if (!getHelper().isWholeTestUniverse()) {
      helper.setUniverseScope(getDefaultUniverseScope());
    }
    return queryResult;
  }

  // Parse the universe if the universe has not been set manually through the helper.
  private void maybeParseUniverseScope(String query) throws Exception {
    if (!getHelper()
        .getUniverseScope()
        .equals(Collections.singletonList(getDefaultUniverseScope()))) {
      return;
    }
    QueryExpression expression = QueryParser.parse(query, getDefaultFunctions());
    Set<String> targetPatternSet = new LinkedHashSet<>();
    expression.collectTargetPatterns(targetPatternSet);
    if (!targetPatternSet.isEmpty()) {
      StringBuilder universeScope = new StringBuilder();
      for (String target : targetPatternSet) {
        universeScope.append(target).append(",");
      }
      helper.setUniverseScope(universeScope.toString());
    }
  }

  protected abstract HashMap<String, QueryFunction> getDefaultFunctions();

  protected abstract BuildConfiguration getConfiguration(T target);

  protected ConfiguredRuleClassProvider.Builder setRuleClassProviders(MockRule... mockRules) {
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    for (MockRule rule : mockRules) {
      builder.addRuleDefinition(rule);
    }
    return builder;
  }

  @Override
  protected boolean testConfigurableAttributes() {
    // ConfiguredTargetQuery knows the actual configuration, so it doesn't falsely overapproximate.
    return false;
  }

  @After
  public void cleanUpHelper() {
    getHelper().cleanUp();
    helper = null;
  }

  @Override
  @Test
  public void testTargetLiteralWithMissingTargets() throws Exception {
    getHelper().turnOffFailFast();
    super.testTargetLiteralWithMissingTargets();
  }

  @Override
  @Test
  public void testBadTargetLiterals() throws Exception {
    getHelper().turnOffFailFast();
    super.testBadTargetLiterals();
  }

  @Override
  @Test
  public void testNoImplicitDeps() throws Exception {
    MockRule ruleWithImplicitDeps =
        () ->
            MockRule.define(
                "implicit_deps_rule",
                attr("explicit", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE),
                attr("explicit_with_default", LABEL)
                    .value(Label.parseAbsoluteUnchecked("//test:explicit_with_default"))
                    .allowedFileTypes(FileTypeSet.ANY_FILE),
                attr("$implicit", LABEL).value(Label.parseAbsoluteUnchecked("//test:implicit")),
                attr(":latebound", LABEL)
                    .value(
                        Attribute.LateBoundDefault.fromConstantForTesting(
                            Label.parseAbsoluteUnchecked("//test:latebound"))));
    helper.useRuleClassProvider(setRuleClassProviders(ruleWithImplicitDeps).build());

    writeFile(
        "test/BUILD",
        "implicit_deps_rule(",
        "    name = 'my_rule',",
        "    explicit = ':explicit',",
        "    explicit_with_default = ':explicit_with_default',",
        ")",
        "cc_library(name = 'explicit')",
        "cc_library(name = 'explicit_with_default')",
        "cc_library(name = 'implicit')",
        "cc_library(name = 'latebound')");

    final String implicits = "//test:implicit + //test:latebound";
    final String explicits = "//test:my_rule + //test:explicit + //test:explicit_with_default";

    // Check for implicit dependencies (late bound attributes, implicit attributes, platforms)
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .containsAtLeastElementsIn(
            evalToListOfStrings(explicits + " + " + implicits + " + " + PLATFORM_LABEL));

    helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .containsAtLeastElementsIn(evalToListOfStrings(explicits));
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .doesNotContain(evalToListOfStrings(implicits));
  }

  @Test
  public void testNoImplicitDeps_toolchains() throws Exception {
    MockRule ruleWithImplicitDeps =
        () ->
            MockRule.define(
                "implicit_toolchain_deps_rule",
                (builder, env) ->
                    builder.addRequiredToolchains(
                        Label.parseAbsoluteUnchecked("//test:toolchain_type")));
    helper.useRuleClassProvider(setRuleClassProviders(ruleWithImplicitDeps).build());

    writeFile(
        "test/toolchain.bzl",
        "def _impl(ctx):",
        "  toolchain = platform_common.ToolchainInfo()",
        "  return [toolchain]",
        "test_toolchain = rule(",
        "    implementation = _impl,",
        ")");
    writeFile(
        "test/BUILD",
        "load(':toolchain.bzl', 'test_toolchain')",
        "implicit_toolchain_deps_rule(",
        "    name = 'my_rule',",
        ")",
        "toolchain_type(name = 'toolchain_type')",
        "toolchain(",
        "    name = 'toolchain',",
        "    toolchain_type = ':toolchain_type',",
        "    toolchain = ':toolchain_impl',",
        ")",
        "test_toolchain(name = 'toolchain_impl')");
    ((PostAnalysisQueryHelper<T>) helper).useConfiguration("--extra_toolchains=//test:toolchain");

    String implicits = "//test:toolchain_impl";
    String explicits = "//test:my_rule";

    // Check for implicit toolchain dependencies
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .containsAtLeastElementsIn(
            evalToListOfStrings(explicits + " + " + implicits + " + " + PLATFORM_LABEL));

    helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .containsAtLeastElementsIn(evalToListOfStrings(explicits));
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .doesNotContain(evalToListOfStrings(implicits));
  }

  // Regression test for b/148550864
  @Test
  public void testNoImplicitDeps_platformDeps() throws Exception {
    MockRule simpleRule = () -> MockRule.define("simple_rule");
    helper.useRuleClassProvider(setRuleClassProviders(simpleRule).build());

    writeFile(
        "test/BUILD",
        "simple_rule(name = 'my_rule')",
        "platform(name = 'host_platform')",
        "platform(name = 'execution_platform')");

    ((PostAnalysisQueryHelper<T>) helper)
        .useConfiguration(
            "--host_platform=//test:host_platform",
            "--extra_execution_platforms=//test:execution_platform");

    // Check for platform dependencies
    assertThat(evalToListOfStrings("deps(//test:my_rule)"))
        .containsAtLeastElementsIn(
            evalToListOfStrings("//test:execution_platform + //test:host_platform"));
    helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);
    assertThat(evalToListOfStrings("deps(//test:my_rule)")).containsExactly("//test:my_rule");
  }

  @Test
  public void testNoImplicitDeps_computedDefault() throws Exception {
    MockRule computedDefaultRule =
        () ->
            MockRule.define(
                "computed_default_rule",
                attr("conspiracy", Type.STRING).value("space jam was a documentary"),
                attr("dep", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .value(
                        new Attribute.ComputedDefault("conspiracy") {
                          @Override
                          public Object getDefault(AttributeMap rule) {
                            return rule.get("conspiracy", Type.STRING)
                                    .equals("space jam was a documentary")
                                ? Label.parseAbsoluteUnchecked("//test:foo")
                                : null;
                          }
                        }));

    helper.useRuleClassProvider(setRuleClassProviders(computedDefaultRule).build());

    writeFile("test/BUILD", "cc_library(name = 'foo')", "computed_default_rule(name = 'my_rule')");

    String target = "//test:my_rule";

    assertThat(evalToListOfStrings("deps(" + target + ")")).contains("//test:foo");
    helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);
    assertThat(eval("deps(" + target + ")")).isEqualTo(eval(target));
  }

  @Override
  @Test
  public void testLet() throws Exception {
    getHelper().setWholeTestUniverseScope("//a,//b,//c,//d");
    super.testLet();
  }

  @Override
  @Test
  public void testSet() throws Exception {
    getHelper().setWholeTestUniverseScope("//a:*,//b:*,//c:*,//d:*");
    super.testSet();
  }

  /** PatchTransition on --test_arg */
  public static class TestArgPatchTransition implements PatchTransition {
    String toOption;
    String name;

    public TestArgPatchTransition(String toOption, String name) {
      this.toOption = toOption;
      this.name = name;
    }

    public TestArgPatchTransition(String toOption) {
      this(toOption, "TestArgPatchTransition");
    }

    @Override
    public String getName() {
      return this.name;
    }

    @Override
    public BuildOptions patch(BuildOptions options) {
      BuildOptions result = options.clone();
      result.get(TestOptions.class).testArguments = Collections.singletonList(toOption);
      return result;
    }
  }

  @Test
  public void testMultipleTopLevelConfigurations() throws Exception {
    MockRule transitionedRule =
        () ->
            MockRule.define(
                "transitioned_rule",
                (builder, env) -> builder.cfg(new TestArgPatchTransition("SET BY PATCH")).build());

    MockRule untransitionedRule = () -> MockRule.define("untransitioned_rule");

    helper.useRuleClassProvider(
        setRuleClassProviders(transitionedRule, untransitionedRule).build());

    writeFile(
        "test/BUILD",
        "transitioned_rule(name = 'transitioned_rule')",
        "untransitioned_rule(name = 'untransitioned_rule')");

    Set<T> result = eval("//test:transitioned_rule+//test:untransitioned_rule");

    assertThat(result).hasSize(2);

    Iterator<T> resultIterator = result.iterator();
    assertThat(getConfiguration(resultIterator.next()))
        .isNotEqualTo(getConfiguration(resultIterator.next()));
  }

  @Test
  public abstract void testMultipleTopLevelConfigurations_nullConfigs() throws Exception;

  @Test
  public void testMultipleTopLevelConfigurations_multipleConfigsPrefersTopLevel() throws Exception {
    MockRule ruleWithTransitionAndDep =
        () ->
            MockRule.define(
                "rule_with_transition_and_dep",
                (builder, env) ->
                    builder
                        .cfg(new TestArgPatchTransition("SET BY PATCH"))
                        .addAttribute(
                            attr("dep", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE).build())
                        .build());

    MockRule simpleRule = () -> MockRule.define("simple_rule");

    helper.useRuleClassProvider(
        setRuleClassProviders(ruleWithTransitionAndDep, simpleRule).build());

    writeFile(
        "test/BUILD",
        "rule_with_transition_and_dep(name = 'top-level', dep = ':dep')",
        "simple_rule(name = 'dep')");

    helper.setUniverseScope("//test:*");

    assertThat(getConfiguration(Iterables.getOnlyElement(eval("//test:dep"))))
        .isNotEqualTo(getConfiguration(Iterables.getOnlyElement(eval("//test:top-level"))));
  }

  // LabelListAttr not currently supported.
  @Override
  public void testLabelsOperator() {}

  // Wants to get the query environment without evaluation -- not worth it.
  @Override
  @Test
  public void testEqualityOfOrderedThreadSafeImmutableSet() {}

  @Override
  public void testDefaultCopts() {}

  @Override
  public void testHdrsCheck() {}

  @Override
  public void testFilesetPackageDeps() {}

  @Override
  public void testRegressionBug1686119() {}

  // The actual crosstool-related targets depended on are not the nominal crosstool label the test
  // expects.

  // "Extended rules" don't play nicely with actual analysis.
  @Override
  public void testNoDepsOnAspectAttributeWhenAspectMissing() {}

  @Override
  public void testNoDepsOnAspectAttributeWithNoImpicitDeps() {}

  @Override
  public void testHaveDepsOnAspectsAttributes() {}

  // Can't handle loading-phase errors.
  @Override
  public void testStrictTestSuiteWithFile() {}

  @Override
  public void testTestsOperatorReportsMissingTargets() {}

  @Override
  public void testCycleInSkylark() {}

  @Override
  public void testCycleInSkylarkParentDir() {}

  @Override
  public void testCycleInSubpackage() {}

  @Override
  public void testRegression1309697() {}

  // Can't handle cycles.
  @Override
  public void testDotDotDotWithCycle() {}

  @Override
  public void testDotDotDotWithUnrelatedCycle() {}

  // ...
  @Override
  public void testQueryTimeLoadingTargetsBelowNonPackageDirectory() {}

  @Override
  public void testQueryTimeLoadingOfTargetsBelowPackageHappyPath() {}

  @Override
  public void testQueryTimeLoadingTargetsBelowMissingPackage() {}

  // These tests clear the universe, getting rid of mock tools that are needed for analysis. Disable
  // at least for now. Other than testSlashSlashDotDotDot, they're only testing visibility anyway.

  @Override
  public void testSlashSlashDotDotDot() {}

  @Override
  public void testVisible_default_private() {}

  @Override
  public void testVisible_default_public() {}

  @Override
  public void testPackageGroupAllBeneath() {}

  @Override
  public void testVisible_java_javatests() {}

  @Override
  public void testVisible_java_javatests_different_package() {}

  @Override
  public void testVisible_javatests_java() {}

  @Override
  public void testVisible_package_group() {}

  @Override
  public void testVisible_package_group_include() {}

  @Override
  public void testVisible_package_group_invisible() {}

  @Override
  public void testVisible_private_same_package() {}

  @Override
  public void testVisible_simple_different_subpackages() {}

  @Override
  public void testVisible_simple_package() {}

  @Override
  public void testVisible_simple_private() {}

  @Override
  public void testVisible_simple_public() {}

  @Override
  public void testVisible_simple_subpackages() {}

  // test_suite rules aren't supported, since they're not configured targets.

  @Override
  public void testTestsOperatorFiltersByNegativeTag() {}

  @Override
  public void testTestsOperatorCrossesPackages() {}

  @Override
  public void testTestsOperatorHandlesCyclesGracefully() {}

  @Override
  public void testTestSuiteInTestsAttributeAndViceVersa() {}

  @Override
  public void testAmbiguousAllResolvesToTestSuiteNamedAll() {}

  @Override
  public void testTestSuiteWithFile() {}

  @Override
  public void testTestsOperatorFiltersByTagSizeAndEnv() {}

  @Override
  public void testTestsOperatorExpandsTestsAndExcludesNonTests() {}

  // buildfiles() operator.
  @Override
  public void testBuildFiles() {}

  @Override
  public void testBuildFilesDoesNotReturnVisibilityOfBUILD() {}

  @Override
  public void testBuildFilesDoesNotReturnVisibilityOfRule() {}

  @Override
  public void testBuildfilesOfBuildfiles() {}

  @Override
  public void testBuildfilesWithDuplicates() {}

  @Override
  public void testTargetsFromBuildfilesAndRealTargets() {}

  // siblings() operator.

  @Override
  public void testSiblings_DuplicatePackages() {}

  @Override
  public void testSiblings_SamePackageRdeps() {}

  @Override
  public void testSiblings_MatchesTargetNamedAll() {}

  @Override
  public void testSiblings_Simple() {}

  @Override
  public void testSiblings_WithBuildfiles() {}

  // same_pkg_direct_rdeps() operator.

  @Override
  public void testSamePackageRdeps_simple() throws Exception {}

  @Override
  public void testSamePackageRdeps_duplicate() throws Exception {}

  @Override
  public void testSamePackageRdeps_two() throws Exception {}

  @Override
  public void testSamePackageRdeps_twoPackages() throws Exception {}

  @Override
  public void testSamePackageRdeps_crissCross() throws Exception {}

  // We eagerly load all packages, so can't test that we don't load one.
  @Override
  @Test
  public void testWildcardsDontLoadUnnecessaryPackages() {}

  // Query needs a graph.
  @Override
  @Test
  public void testGraphOrderOfWildcards() {}

  // Visibility is checked in the analysis phase, so the post-analysis query done in this unit test
  // would never occur because the visibility error would occur first.
  @Override
  @Test
  public void testVisibleWithNonPackageGroupVisibility() throws Exception {}

  // Visibility is checked in the analysis phase, so the post-analysis query done in this unit test
  // would never occur because the visibility error would occur first.
  @Override
  @Test
  public void testVisibleWithPackageGroupWithNonPackageGroupIncludes() throws Exception {}

  // We don't support --nodep_deps=false.
  @Override
  @Test
  public void testNodepDeps_False() throws Exception {}

  // package_group instances have a null configuration and are filtered out by --host_deps=false.
  @Override
  @Test
  public void testDefaultVisibilityReturnedInDeps_NonEmptyDependencyFilter() throws Exception {}
}
