// Copyright 2020 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.buildtool;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertDoesNotContainEvent;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.testing.GcFinalization;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.events.EventCollector;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import java.lang.ref.WeakReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Miscellaneous tests of the analysis phase. (Sometimes it's easier to express these in terms of
 * the BuildTool than of the BuildView because the latter's class interface is quite complex.)
 */
@RunWith(JUnit4.class)
public class MiscAnalysisTest extends BuildIntegrationTestCase {

  @Test
  public void testWarningsNotReplayed() throws Exception {
    AnalysisMock.get().pySupport().setup(mockToolsConfig);
    write(
        "y/BUILD",
        "genrule(name='y', outs=['y.out'], cmd='touch $@', deprecation='generate a warning')");
    addOptions("--nobuild");

    buildTarget("//y");
    events.assertContainsWarning("target '//y:y' is deprecated");

    events.clear();

    buildTarget("//y");
    events.assertDoesNotContainEvent("target '//y:y' is deprecated");
  }

  @Test
  public void testDeprecatedTargetOnCommandLine() throws Exception {
    write(
        "raspberry/BUILD",
        "sh_library(name='raspberry', srcs=['raspberry.sh'], deprecation='rotten')");
    addOptions("--nobuild");
    buildTarget("//raspberry:raspberry");
    events.assertContainsWarning("target '//raspberry:raspberry' is deprecated: rotten");
  }

  @Test
  public void targetAnalyzedInTwoConfigurations_deprecationWarningDisplayedOncePerBuild()
      throws Exception {
    // :a depends on :dep in the target configuration. :b depends on :dep in the exec configuration.
    write(
        "foo/BUILD",
        "genrule(name = 'a', outs = ['a.out'], srcs = [':dep'], cmd = 'touch $@')",
        "genrule(name = 'b', outs = ['b.out'], tools = [':dep'], cmd = 'touch $@')",
        "genrule(name = 'dep', outs = ['dep.out'], srcs = ['//deprecated'], cmd = 'touch $@')");
    write("deprecated/BUILD", "sh_library(name = 'deprecated', deprecation = 'old')");
    addOptions("--nobuild");
    buildTarget("//foo:a", "//foo:b");
    events.assertContainsEventWithFrequency(
        "'//foo:dep' depends on deprecated target '//deprecated:deprecated'", 1);

    events.clear();

    // Edit to force re-analysis.
    write("deprecated/BUILD", "sh_library(name = 'deprecated', deprecation = 'very old')");
    buildTarget("//foo:a", "//foo:b");
    events.assertContainsEventWithFrequency(
        "'//foo:dep' depends on deprecated target '//deprecated:deprecated'", 1);
  }

  // Regression test for http://b/12465751: "IllegalStateException in ParallelEvaluator".
  @Test
  public void testShBinaryTwoSrcs() throws Exception {
    write("sh/BUILD", "sh_test(name = 'double', srcs = ['a','b'])");
    addOptions("--nobuild");

    assertThrows(Exception.class, () -> buildTarget("//sh:double"));
    events.assertContainsError("you must specify exactly one file in 'srcs'");
  }

  // Note that the cache_analysis flag has been deleted, as it is now standard app behavior.
  @Test
  public void testAnalysisCachingAndKeepGoing() throws Exception {
    write(
        "fruit/BUILD",
        "cc_library(name='apple', deps=[':banana'])",
        "cc_library(name='banana', deps=[':cherry'])",
        "cc_library(name='cherry', deps=[':durian__hdrs__'])",
        "genrule(name='durian', outs=['durian.out'], cmd=':')");
    addOptions("--nobuild", "--keep_going");

    BuildFailedException e =
        assertThrows(BuildFailedException.class, () -> buildTarget("//fruit:apple"));
    assertThat(e).hasMessageThat().contains("command succeeded");
    events.assertContainsError(
        "in deps attribute of cc_library rule //fruit:cherry: "
            + "target '//fruit:durian__hdrs__' does not exist");

    events.clear();
    e = assertThrows(BuildFailedException.class, () -> buildTarget("//fruit:apple"));
    assertThat(e).hasMessageThat().contains("command succeeded");
    events.assertContainsError(
        "in deps attribute of cc_library rule //fruit:cherry: "
            + "target '//fruit:durian__hdrs__' does not exist");
  }

  // Note that the cache_analysis flag has been deleted, as it is now standard app behavior.
  @Test
  public void testErrorsAreReplayedEvenWithAnalysisCaching() throws Exception {
    write(
        "fruit/BUILD",
        "cc_library(name='apple', deps=[':banana__hdrs__'])",
        "genrule(name='banana', outs=['banana.out'], cmd=':')");
    addOptions("--nobuild");

    assertThrows(ViewCreationFailedException.class, () -> buildTarget("//fruit:apple"));
    events.assertContainsError(
        "in deps attribute of cc_library rule //fruit:apple: "
            + "target '//fruit:banana__hdrs__' does not exist");

    events.clear();
    assertThrows(ViewCreationFailedException.class, () -> buildTarget("//fruit:apple"));
    events.assertContainsError(
        "in deps attribute of cc_library rule //fruit:apple: "
            + "target '//fruit:banana__hdrs__' does not exist");
  }

  @Test
  public void testBuildAllAndParsingError() throws Exception {
    write("pkg/BUILD",
          "java_binary(",
          "name = \"foo\",",
          "  syntax error here",
          ")");

    addOptions("--nobuild");

    Exception e = assertThrows(Exception.class, () -> buildTarget("//pkg:all"));
    events.assertContainsError("syntax error at 'error'");
    assertPkgErrorMsg(e);
  }

  @Test
  public void testDiscardAnalysisCache() throws Exception {
    write("sh/BUILD",
        "sh_library(name = 'sh', srcs = [], deps = [':dep'])",
        "sh_library(name = 'dep', srcs = [])"
        );
    buildTarget("//sh:sh");
    // We test with dep because target completion middleman actions keep references to the
    // top-level configured targets.
    ConfiguredTarget ct = getConfiguredTarget("//sh:dep");
    addOptions("--discard_analysis_cache");
    buildTarget("//sh:sh");
    addOptions("--nodiscard_analysis_cache");
    buildTarget("//sh:sh");
    // Configured target was replaced.
    ConfiguredTarget newCt = getConfiguredTarget("//sh:dep");
    assertThat(newCt).isNotSameInstanceAs(ct);
    WeakReference<ConfiguredTarget> ref = new WeakReference<>(newCt);
    newCt = null;
    addOptions("--discard_analysis_cache");
    buildTarget("//sh:sh");
    GcFinalization.awaitClear(ref);
  }

  @Test
  public void testDiscardAnalysisCacheWithError() throws Exception {
    write(
        "x/BUILD",
        "cc_library(name='x', deps=[':z__hdrs__'])",
        "genrule(name='z', outs=['z.out'], cmd=':')");
    write("y/BUILD", "sh_library(name='y')");
    addOptions("--discard_analysis_cache", "--keep_going");
    EventCollector collector = new EventCollector(EventKind.STDERR);
    events.addHandler(collector);
    assertThrows(BuildFailedException.class, () -> buildTarget("//x:x", "//y:y"));
    events.assertContainsError(
        "in deps attribute of cc_library rule //x:x: target '//x:z__hdrs__' does not exist");
    MoreAsserts.assertContainsEvent(collector, "Target //y:y up-to-date", EventKind.STDERR);
  }

  @Test
  public void testBuildAllAndEvaluationError() throws Exception {
    write("pkg/BUILD",
          "java_binary(",
          "    name = \"foo\",",
          "    srcs = unknown_value,",
          ")");

    addOptions("--nobuild");

    Exception e = assertThrows(Exception.class, () -> buildTarget("//pkg:all"));
    events.assertContainsError("name 'unknown_value' is not defined");
    assertPkgErrorMsg(e);
  }

  private static void assertPkgErrorMsg(Exception e) {
    assertThat(e).hasMessageThat().containsMatch("[pP]ackage.*contains errors");
  }

  @Test
  public void testNoTestTargetsFoundMessageForBuildCommand() throws Exception {
    write("pkg/BUILD");
    for (String option : ImmutableList.of("", "--nobuild", "--noanalyze")) {
      resetOptions();
      addOptions(option);
      buildTarget("//pkg:all");
      assertDoesNotContainEvent(events.infos(), "test target");
    }
  }
}
