// Copyright 2022 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.common.collect.ImmutableList;
import com.google.common.truth.Correspondence;
import com.google.devtools.build.lib.analysis.test.AnalysisFailure;
import com.google.devtools.build.lib.analysis.test.AnalysisFailureInfo;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import javax.annotation.Nullable;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkSemantics;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Tests verifying analysis failure propagation via {@link AnalysisFailureInfo} when {@code
 * --allow_analysis_failures=true}.
 */
@RunWith(TestParameterInjector.class)
public final class AnalysisFailureInfoTest extends BuildViewTestCase {

  @Before
  public void setUp() throws Exception {
    useConfiguration("--allow_analysis_failures=true");
  }

  @Test
  public void analysisFailureInfoStarlarkApi() throws Exception {
    Label label = Label.create("test", "test");
    AnalysisFailure failure = new AnalysisFailure(label, "ErrorMessage");
    assertThat(getattr(failure, "label")).isSameInstanceAs(label);
    assertThat(getattr(failure, "message")).isEqualTo("ErrorMessage");

    AnalysisFailureInfo info = AnalysisFailureInfo.forAnalysisFailures(ImmutableList.of(failure));
    // info.causes.to_list()[0] == failure
    NestedSet<AnalysisFailure> causes =
        Depset.cast(getattr(info, "causes"), AnalysisFailure.class, "causes");
    assertThat(causes.toList().get(0)).isSameInstanceAs(failure);
  }

  private static Object getattr(Object x, String name) throws Exception {
    return Starlark.getattr(/*mu=*/ null, StarlarkSemantics.DEFAULT, x, name, null);
  }

  /** Regression test for b/154007057 (rule name) and b/186685477 (output file). */
  @Test
  public void nativeRuleExpanderFailure(
      @TestParameter({"//test:bad_variable", "//test:bad_variable.out"}) String targetToRequest)
      throws Exception {
    scratch.file(
        "test/BUILD",
        "genrule(",
        "    name = 'bad_variable',",
        "    outs = ['bad_variable.out'],",
        "    cmd = 'cp $< $@',  # Error to use $< with no srcs",
        ")");

    ConfiguredTarget target = getConfiguredTarget(targetToRequest);
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
    assertThat(failure.getMessage()).contains("variable '$<' : no input file");
    assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:bad_variable"));
  }

  /** Regression test for b/154007057. */
  @Test
  public void nativeRuleConfiguredTargetFactoryCreateReturningNull() throws Exception {
    scratch.file(
        "test/BUILD",
        "native_rule_with_failing_configured_target_factory(",
        "    name = 'bad_factory',",
        ")");

    ConfiguredTarget target = getConfiguredTarget("//test:bad_factory");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
    assertThat(failure.getMessage()).contains("FailingRuleConfiguredTargetFactory.create() fails");
    assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:bad_factory"));
  }

  /** Dummy factory whose {@code create()} method always returns {@code null}. */
  public static final class FailingRuleConfiguredTargetFactory
      implements RuleConfiguredTargetFactory {
    @Override
    @Nullable
    public ConfiguredTarget create(RuleContext ruleContext) {
      ruleContext.ruleError("FailingRuleConfiguredTargetFactory.create() fails");
      return null;
    }
  }

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder =
        new ConfiguredRuleClassProvider.Builder()
            .addRuleDefinition(
                ((MockRule)
                    () ->
                        MockRule.factory(FailingRuleConfiguredTargetFactory.class)
                            .define("native_rule_with_failing_configured_target_factory")));
    TestRuleClassProvider.addStandardRules(builder);
    return builder.build();
  }

  private static final Correspondence<AnalysisFailure, AnalysisFailure>
      analysisFailureCorrespondence =
          Correspondence.from(
              (actual, expected) ->
                  actual.getLabel().equals(expected.getLabel())
                      && actual.getMessage().contains(expected.getMessage()),
              "is equivalent to");

  @Test
  public void starlarkRuleFailure() throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_rule_impl(ctx):",
        "   fail('This Is My Failure Message')",
        "",
        "custom_rule = rule(implementation = custom_rule_impl)");

    scratch.file(
        "test/BUILD", "load('//test:extension.bzl', 'custom_rule')", "", "custom_rule(name = 'r')");

    ConfiguredTarget target = getConfiguredTarget("//test:r");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
    assertThat(failure.getMessage()).contains("This Is My Failure Message");
    assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:r"));
  }

  @Test
  public void starlarkRuleFailure_forTest() throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_rule_impl(ctx):",
        "   fail('This Is My Failure Message')",
        "",
        "custom_test = rule(implementation = custom_rule_impl,",
        "    test = True)");

    scratch.file(
        "test/BUILD", "load('//test:extension.bzl', 'custom_test')", "", "custom_test(name = 'r')");

    ConfiguredTarget target = getConfiguredTarget("//test:r");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
    assertThat(failure.getMessage()).contains("This Is My Failure Message");
    assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:r"));
  }

  @Test
  public void starlarkRuleFailure_withOutput() throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_rule_impl(ctx):",
        "   fail('This Is My Failure Message')",
        "",
        "custom_rule = rule(implementation = custom_rule_impl,",
        "    outputs = {'my_output': '%{name}.txt'})");

    scratch.file(
        "test/BUILD", "load('//test:extension.bzl', 'custom_rule')", "", "custom_rule(name = 'r')");

    ConfiguredTarget target = getConfiguredTarget("//test:r");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
    assertThat(failure.getMessage()).contains("This Is My Failure Message");
    assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:r"));
  }

  @Test
  public void transitiveStarlarkRuleFailure() throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_rule_impl(ctx):",
        "   fail('This Is My Failure Message')",
        "",
        "custom_rule = rule(implementation = custom_rule_impl)",
        "",
        "def depending_rule_impl(ctx):",
        "   return []",
        "",
        "depending_rule = rule(implementation = depending_rule_impl,",
        "     attrs = {'deps' : attr.label_list()})");

    scratch.file(
        "test/BUILD",
        "load('//test:extension.bzl', 'custom_rule', 'depending_rule')",
        "",
        "custom_rule(name = 'one')",
        "custom_rule(name = 'two')",
        "depending_rule(name = 'failures_are_direct_deps',",
        "    deps = [':one', ':two'])",
        "depending_rule(name = 'failures_are_indirect_deps',",
        "    deps = [':failures_are_direct_deps'])");

    ConfiguredTarget target = getConfiguredTarget("//test:failures_are_indirect_deps");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());

    AnalysisFailure expectedOne =
        new AnalysisFailure(
            Label.parseAbsoluteUnchecked("//test:one"), "This Is My Failure Message");
    AnalysisFailure expectedTwo =
        new AnalysisFailure(
            Label.parseAbsoluteUnchecked("//test:two"), "This Is My Failure Message");

    assertThat(info.getCausesNestedSet().toList())
        .comparingElementsUsing(analysisFailureCorrespondence)
        .containsExactly(expectedOne, expectedTwo);
  }

  @Test
  public void starlarkAspectFailure() throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_aspect_impl(target, ctx):",
        "   fail('This Is My Aspect Failure Message')",
        "",
        "custom_aspect = aspect(implementation = custom_aspect_impl, attr_aspects = ['deps'])",
        "",
        "def custom_rule_impl(ctx):",
        "   return []",
        "",
        "custom_rule = rule(implementation = custom_rule_impl,",
        "     attrs = {'deps' : attr.label_list(aspects = [custom_aspect])})");
    scratch.file(
        "test/BUILD",
        "load('//test:extension.bzl', 'custom_rule')",
        "",
        "custom_rule(name = 'one')",
        "custom_rule(name = 'two', deps = [':one'])");

    ConfiguredTarget target = getConfiguredTarget("//test:two");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure expectedOne =
        new AnalysisFailure(
            Label.parseAbsoluteUnchecked("//test:one"), "This Is My Aspect Failure Message");

    assertThat(info.getCausesNestedSet().toList())
        .comparingElementsUsing(analysisFailureCorrespondence)
        .containsExactly(expectedOne);
  }

  @Test
  public void transitiveStarlarkAspectFailure() throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_aspect_impl(target, ctx):",
        "   if hasattr(ctx.rule.attr, 'kaboom') and ctx.rule.attr.kaboom:",
        "       fail('This Is My Aspect Failure Message')",
        "   return []",
        "",
        "custom_aspect = aspect(implementation = custom_aspect_impl, attr_aspects = ['deps'])",
        "",
        "def custom_rule_impl(ctx):",
        "   return []",
        "",
        "custom_rule = rule(implementation = custom_rule_impl,",
        "     attrs = {'deps' : attr.label_list(aspects = [custom_aspect]),",
        "              'kaboom' : attr.bool()})");
    scratch.file(
        "test/BUILD",
        "load('//test:extension.bzl', 'custom_rule')",
        "",
        "custom_rule(name = 'one', kaboom = True)",
        "custom_rule(name = 'two', deps = [':one'])",
        "custom_rule(name = 'three', deps = [':two'])");

    ConfiguredTarget target = getConfiguredTarget("//test:three");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure expectedOne =
        new AnalysisFailure(
            Label.parseAbsoluteUnchecked("//test:one"), "This Is My Aspect Failure Message");

    assertThat(info.getCausesNestedSet().toList())
        .comparingElementsUsing(analysisFailureCorrespondence)
        .containsExactly(expectedOne);
  }

  @Test
  public void starlarkAspectAndRuleFailure_analysisFailureInfoPropagatesOnlyFromRuleFailure()
      throws Exception {
    scratch.file(
        "test/extension.bzl",
        "def custom_aspect_impl(target, ctx):",
        "   fail('This Is My Aspect Failure Message')",
        "",
        "custom_aspect = aspect(implementation = custom_aspect_impl, attr_aspects = ['deps'])",
        "",
        "def custom_rule_impl(ctx):",
        "   fail('This Is My Rule Failure Message')",
        "",
        "custom_rule = rule(implementation = custom_rule_impl,",
        "     attrs = {'deps' : attr.label_list(aspects = [custom_aspect])})");
    scratch.file(
        "test/BUILD",
        "load('//test:extension.bzl', 'custom_rule')",
        "",
        "custom_rule(name = 'one')",
        "custom_rule(name = 'two', deps = [':one'])");

    ConfiguredTarget target = getConfiguredTarget("//test:two");
    AnalysisFailureInfo info =
        (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
    AnalysisFailure expectedRuleFailure =
        new AnalysisFailure(
            Label.parseAbsoluteUnchecked("//test:one"), "This Is My Rule Failure Message");

    assertThat(info.getCausesNestedSet().toList())
        .comparingElementsUsing(analysisFailureCorrespondence)
        .containsExactly(expectedRuleFailure);
  }
}
