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

import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.analysis.config.BuildConfigurationValue.configurationIdMessage;
import static com.google.devtools.build.lib.buildeventstream.BuildEventIdUtil.configurationIdMessage;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.eventbus.Subscribe;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.causes.AnalysisFailedCause;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.causes.LoadingFailedCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.server.FailureDetails.Analysis;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.server.FailureDetails.PackageLoading;
import com.google.devtools.build.lib.server.FailureDetails.PackageLoading.Code;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Collection;
import java.util.HashMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Analysis failure reporting tests. */
@RunWith(JUnit4.class)
public class AnalysisFailureReportingTest extends AnalysisTestCase {
  private final AnalysisFailureEventCollector collector = new AnalysisFailureEventCollector();

  // TODO(mschaller): The below is closer now because of e.g. DetailedExitCode/FailureDetail.
  // original(ulfjack): Don't check for exact error message wording; instead, add machine-readable
  // details to the events, and check for those. Also check if we can remove duplicate test coverage
  // for these errors, i.e., consolidate the failure reporting tests in this class.

  @Before
  public void setup() {
    // We only test failure cases in this class.
    reporter.removeHandler(failFastHandler);
    eventBus.register(collector);
  }

  @Test
  public void testMissingRequiredAttribute() throws Exception {
    scratch.file(
        "foo/BUILD",
        "genrule(name = 'foo',", // missing "out" attribute
        "        cmd = '')");
    AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//foo");
    assertThat(result.hasError()).isTrue();
    Label topLevel = Label.parseCanonicalUnchecked("//foo");

    assertThat(collector.events.keySet()).containsExactly(topLevel);

    Collection<Cause> topLevelCauses = collector.events.get(topLevel);
    assertThat(topLevelCauses).hasSize(1);

    Cause cause = Iterables.getOnlyElement(topLevelCauses);
    assertThat(cause).isInstanceOf(LoadingFailedCause.class);
    assertThat(cause.getLabel()).isEqualTo(topLevel);
    assertThat(((LoadingFailedCause) cause).getMessage())
        .isEqualTo(
            "Target '//foo:foo' contains an error and its package is in error: //foo:foo: missing"
                + " value for mandatory attribute 'outs' in 'genrule' rule");
  }

  @Test
  public void testMissingDependency() throws Exception {
    scratch.file(
        "foo/BUILD",
        "genrule(name = 'foo',",
        "        tools = ['//bar'],",
        "        cmd = 'command',",
        "        outs = ['foo.txt'])");
    AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//foo");
    assertThat(result.hasError()).isTrue();
    Label topLevel = Label.parseCanonicalUnchecked("//foo");
    Label causeLabel = Label.parseCanonicalUnchecked("//bar");
    assertThat(collector.events.keySet()).containsExactly(topLevel);
    assertThat(collector.events.get(topLevel))
        .containsExactly(
            new AnalysisFailedCause(
                causeLabel,
                configurationIdMessage(
                    getOnlyElement(collector.failedTargets.values()).getConfigurationKey()),
                createPackageLoadingDetailedExitCode(
                    "BUILD file not found in any of the following"
                        + " directories. Add a BUILD file to a directory to mark it as a"
                        + " package.\n"
                        + " - /workspace/bar",
                    Code.BUILD_FILE_MISSING)));
  }

  @Test
  public void testExpanderFailure() throws Exception {
    scratch.file(
        "test/BUILD",
        "genrule(",
        "    name = 'bad',",
        "    outs = ['bad.out'],",
        "    cmd = 'cp $< $@',  # Error to use $< with no srcs",
        ")");
    AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//test:bad");
    assertThat(result.hasError()).isTrue();
    Label topLevel = Label.parseCanonicalUnchecked("//test:bad");
    assertThat(collector.events.keySet()).containsExactly(topLevel);
    assertThat(collector.events)
        .valuesForKey(topLevel)
        .containsExactly(
            new AnalysisFailedCause(
                topLevel,
                configurationIdMessage(
                    getOnlyElement(collector.failedTargets.values()).getConfigurationKey()),
                createAnalysisDetailedExitCode(
                    "in cmd attribute of genrule rule //test:bad: variable '$<' : no input file")));
  }

  /**
   * This error gets reported twice - once when we try to analyze the //cycles1 target, and the
   * other time when we analyze the //c target (which depends on //cycles1). This test checks that
   * both use the same error message.
   */
  @Test
  public void testSymlinkCycleReportedExactlyOnce() throws Exception {
    scratch.file("gp/BUILD", "sh_library(name = 'gp', deps = ['//p'])");
    scratch.file("p/BUILD", "sh_library(name = 'p', deps = ['//c'])");
    scratch.file("c/BUILD", "sh_library(name = 'c', deps = ['//cycles1'])");
    Path cycles1BuildFilePath =
        scratch.file("cycles1/BUILD", "sh_library(name = 'cycles1', srcs = glob(['*.sh']))");
    cycles1BuildFilePath
        .getParentDirectory()
        .getRelative("cycles1.sh")
        .createSymbolicLink(PathFragment.create("cycles1.sh"));

    AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//gp");
    assertThat(result.hasError()).isTrue();

    Label topLevel = Label.parseCanonicalUnchecked("//gp");
    String message =
        "Symlink issue while evaluating globs: Symlink cycle:" + " /workspace/cycles1/cycles1.sh";
    Code code = Code.EVAL_GLOBS_SYMLINK_ERROR;
    assertThat(collector.events.get(topLevel))
        .containsExactly(
            new AnalysisFailedCause(
                Label.parseCanonical("//cycles1"),
                configurationIdMessage(collector.failedTargets.get(topLevel).getConfigurationKey()),
                createPackageLoadingDetailedExitCode(message, code)));
  }

  @Test
  public void testVisibilityError() throws Exception {
    scratch.file("foo/BUILD", "sh_library(name = 'foo', deps = ['//bar'])");
    scratch.file("bar/BUILD", "sh_library(name = 'bar', visibility = ['//visibility:private'])");

    AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//foo");
    assertThat(result.hasError()).isTrue();

    Label topLevel = Label.parseCanonicalUnchecked("//foo");
    assertThat(collector.events.get(topLevel))
        .containsExactly(
            new AnalysisFailedCause(
                Label.parseCanonical("//foo"),
                configurationIdMessage(
                    getOnlyElement(collector.failedTargets.values()).getConfigurationKey()),
                createAnalysisDetailedExitCode(
                    "in sh_library rule //foo:foo: target '//bar:bar' is not visible from"
                        + " target '//foo:foo'. Check the visibility declaration of the"
                        + " former target if you think the dependency is legitimate")));
  }

  @Test
  public void testFileVisibilityError() throws Exception {
    scratch.file("foo/BUILD", "sh_library(name = 'foo', srcs = ['//bar:bar.sh'])");
    scratch.file("bar/BUILD", "exports_files(['bar.sh'], visibility = ['//visibility:private'])");
    scratch.file("bar/bar.sh");

    AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//foo");
    assertThat(result.hasError()).isTrue();

    Label topLevel = Label.parseCanonicalUnchecked("//foo");
    assertThat(collector.events)
        .valuesForKey(topLevel)
        .containsExactly(
            new AnalysisFailedCause(
                Label.parseCanonical("//foo"),
                configurationIdMessage(
                    getOnlyElement(collector.failedTargets.values()).getConfigurationKey()),
                DetailedExitCode.of(
                    FailureDetail.newBuilder()
                        .setMessage(
                            "in sh_library rule //foo:foo: target '//bar:bar.sh' is not visible"
                                + " from target '//foo:foo'. Check the visibility declaration of"
                                + " the former target if you think the dependency is legitimate."
                                + " To set the visibility of that source file target, use the"
                                + " exports_files() function")
                        .setAnalysis(
                            Analysis.newBuilder()
                                .setCode(Analysis.Code.CONFIGURED_VALUE_CREATION_FAILED))
                        .build())));
  }

  @Test
  public void testVisibilityErrorNoKeepGoing() throws Exception {
    scratch.file("foo/BUILD", "sh_test(name = 'foo', srcs = ['test.sh'], deps = ['//bar'])");
    scratch.file("bar/BUILD", "sh_library(name = 'bar', visibility = ['//visibility:private'])");

    try {
      update(eventBus, defaultFlags(), "//foo");
    } catch (ViewCreationFailedException e) {
      // Ignored; we check for the correct eventbus event below.
    }

    Label topLevel = Label.parseCanonicalUnchecked("//foo");
    BuildConfigurationValue expectedConfig =
        skyframeExecutor.getSkyframeBuildView().getBuildConfiguration();
    String message =
        "in sh_test rule //foo:foo: target '//bar:bar' is not visible from"
            + " target '//foo:foo'. Check the visibility declaration of the"
            + " former target if you think the dependency is legitimate";
    assertThat(collector.events.get(topLevel))
        .containsExactly(
            new AnalysisFailedCause(
                Label.parseCanonical("//foo"),
                configurationIdMessage(expectedConfig),
                createAnalysisDetailedExitCode(message)));
  }

  public static DetailedExitCode createPackageLoadingDetailedExitCode(String message, Code code) {
    return DetailedExitCode.of(
        FailureDetail.newBuilder()
            .setMessage(message)
            .setPackageLoading(PackageLoading.newBuilder().setCode(code))
            .build());
  }

  public static DetailedExitCode createAnalysisDetailedExitCode(String message) {
    return DetailedExitCode.of(
        FailureDetail.newBuilder()
            .setMessage(message)
            .setAnalysis(
                Analysis.newBuilder().setCode(Analysis.Code.CONFIGURED_VALUE_CREATION_FAILED))
            .build());
  }

  // TODO(ulfjack): Add more tests for
  // - a target that has multiple analysis errors (in the target itself)
  // - a visibility error in a dependency (not in the target itself)
  // - an error in a config condition
  // - a missing top-level target (does that even get this far?)
  // - a top-level target with an InvalidConfigurationException
  // - a top-level target with a ToolchainContextException
  // - a top-level target with a visibility attribute that points to a non-package_group
  // - a top-level target with a package_group that refers to a non-package_group
  // - aspect errors

  /** Class to collect analysis failures. */
  public static class AnalysisFailureEventCollector {
    private final Multimap<Label, Cause> events = HashMultimap.create();
    private final HashMap<Label, ConfiguredTargetKey> failedTargets = new HashMap<>();

    @Subscribe
    public void failureEvent(AnalysisFailureEvent event) {
      ConfiguredTargetKey failedTarget = event.getFailedTarget();
      Label label = failedTarget.getLabel();
      events.putAll(label, event.getRootCauses().toList());
      failedTargets.put(label, failedTarget);
    }
  }
}
