// Copyright 2014 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.ImmutableList.toImmutableList;
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.packages.BuildType.NODEP_LABEL;
import static com.google.devtools.build.lib.syntax.Type.STRING;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import com.google.common.collect.ImmutableList;
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.CoreOptions;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeTransitionData;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests that check that dependency cycles are reported correctly.
 */
@RunWith(JUnit4.class)
public class CircularDependencyTest extends BuildViewTestCase {

  @Test
  public void testOneRuleCycle() throws Exception {
    checkError(
        "cycle",
        "foo.g",
        //error message
        selfEdgeMsg("//cycle:foo.g"),
        // Rule
        "genrule(name = 'foo.g',",
        "        outs = ['Foo.java'],",
        "        srcs = ['foo.g'],",
        "        cmd = 'cat $(SRCS) > $<' )");
  }

  @Test
  public void testDirectPackageGroupCycle() throws Exception {
    checkError(
        "cycle",
        "melon",
        selfEdgeMsg("//cycle:moebius"),
        "package_group(name='moebius', packages=[], includes=['//cycle:moebius'])",
        "sh_library(name='melon', visibility=[':moebius'])");
  }

  @Test
  public void testThreeLongPackageGroupCycle() throws Exception {
    String expectedEvent =
        "cycle in dependency graph:\n"
            + "    //cycle:superman\n"
            + ".-> //cycle:rock\n"
            + "|   //cycle:paper\n"
            + "|   //cycle:scissors\n"
            + "`-- //cycle:rock";
    checkError(
        "cycle",
        "superman",
        expectedEvent,
        "# dummy line",
        "package_group(name='paper', includes=['//cycle:scissors'])",
        "package_group(name='rock', includes=['//cycle:paper'])",
        "package_group(name='scissors', includes=['//cycle:rock'])",
        "sh_library(name='superman', visibility=[':rock'])");

    Event foundEvent = null;
    for (Event event : eventCollector) {
      if (event.getMessage().contains(expectedEvent)) {
        foundEvent = event;
        break;
      }
    }

    assertThat(foundEvent).isNotNull();
    Location location = foundEvent.getLocation();
    assertThat(location.getStartLineAndColumn().getLine()).isEqualTo(3);
    assertThat(location.getPath().toString()).isEqualTo("/workspace/cycle/BUILD");
  }

  /**
   * Test to detect implicit input/output file overlap in rules.
   */
  @Test
  public void testOneRuleImplicitCycleJava() throws Exception {
    Package pkg =
        createScratchPackageForImplicitCycle(
            "cycle", "java_library(name='jcyc',", "      srcs = ['libjcyc.jar', 'foo.java'])");
    assertThrows(NoSuchTargetException.class, () -> pkg.getTarget("jcyc"));
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("rule 'jcyc' has file 'libjcyc.jar' as both an" + " input and an output");
  }

  /**
   * Test not to detect implicit input/output file overlap in rules,
   * when coming from a different package.
   */
  @Test
  public void testInputOutputConflictDifferentPackage() throws Exception {
    Package pkg =
        createScratchPackageForImplicitCycle(
            "googledata/xxx",
            "genrule(name='geo',",
            "    srcs = ['//googledata/geo:geo_info.txt'],",
            "    outs = ['geoinfo.txt'],",
            "    cmd = '$(SRCS) > $@')");
    assertThat(pkg.containsErrors()).isFalse();
  }

  @Test
  public void testTwoRuleCycle() throws Exception {
    scratchRule("b", "rule2", "cc_library(name='rule2',", "           deps=['//a:rule1'])");

    checkError(
        "a",
        "rule1",
        "in cc_library rule //a:rule1: cycle in dependency graph:\n"
            + ".-> //a:rule1\n"
            + "|   //b:rule2\n"
            + "`-- //a:rule1",
        "cc_library(name='rule1',",
        "           deps=['//b:rule2'])");
  }

  @Test
  public void testTwoRuleCycle2() throws Exception {
    reporter.removeHandler(failFastHandler); // expect errors
    scratch.file(
        "x/BUILD", "java_library(name='x', deps=['y'])", "java_library(name='y', deps=['x'])");
    getConfiguredTarget("//x");
    assertContainsEvent("in java_library rule //x:x: cycle in dependency graph");
  }

  @Test
  public void testIndirectOneRuleCycle() throws Exception {
    scratchRule(
        "cycle",
        "foo.h",
        "genrule(name = 'foo.h',",
        "      outs = ['bar.h'],",
        "      srcs = ['foo.h'],",
        "      cmd = 'cp $< $@')");
    checkError(
        "main",
        "mygenrule",
        //error message
        selfEdgeMsg("//cycle:foo.h"),
        // Rule
        "genrule(name='mygenrule',",
        "      outs = ['baz.h'],",
        "      srcs = ['//cycle:foo.h'],",
        "      cmd = 'cp $< $@')");
  }

  private String selfEdgeMsg(String label) {
    return label + " [self-edge]";
  }

  // Regression test for: "IllegalStateException in
  // AbstractConfiguredTarget.initialize()".
  // Failure to mark all cycle-forming nodes when there are *two* cycles led to
  // an attempt to initialise a node we'd already visited.
  @Test
  public void testTwoCycles() throws Exception {
    reporter.removeHandler(failFastHandler); // expect errors
    scratch.file(
        "x/BUILD",
        "genrule(name='b', srcs=['c'], tools=['c'], outs=['b.out'], cmd=':')",
        "genrule(name='c', srcs=['b.out'], outs=[], cmd=':')");
    getConfiguredTarget("//x:b"); // doesn't crash!
    assertContainsEvent("cycle in dependency graph");
  }

  @Test
  public void testAspectCycle() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file("x/BUILD",
        "load('//x:x.bzl', 'aspected', 'plain')",
        // Using data= makes the dependency graph clearer because then the aspect does not propagate
        // from aspectdep through a to b (and c)
        "plain(name = 'a', noaspect_deps = [':b'])",
        "aspected(name = 'b', aspect_deps = ['c'])",
        "plain(name = 'c')",
        "plain(name = 'aspectdep', aspect_deps = ['a'])");

    scratch.file(
        "x/x.bzl",
        "def _impl(ctx):",
        "    return []",
        "",
        "rule_aspect = aspect(",
        "    implementation = _impl,",
        "    attr_aspects = ['aspect_deps'],",
        "    attrs = { '_implicit': attr.label(default = Label('//x:aspectdep')) })",
        "",
        "plain = rule(",
        "    implementation = _impl,",
        "    attrs = { 'aspect_deps': attr.label_list(), 'noaspect_deps': attr.label_list() })",
        "",
        "aspected = rule(",
        "    implementation = _impl,",
        "    attrs = { 'aspect_deps': attr.label_list(aspects = [rule_aspect]) })");

    getConfiguredTarget("//x:a");
    assertContainsEvent("cycle in dependency graph");
    assertContainsEvent("//x:c with aspect //x:x.bzl%rule_aspect");
  }

  /** A late bound dependency which depends on the 'dep' label if the 'define' is in --defines. */
  // TODO(b/65746853): provide a way to do this without passing the entire configuration
  private static final LabelLateBoundDefault<BuildConfiguration> LATE_BOUND_DEP =
      LabelLateBoundDefault.fromTargetConfiguration(
          BuildConfiguration.class,
          null,
          (rule, attributes, config) ->
              config.getCommandLineBuildVariables().containsKey(attributes.get("define", STRING))
                  ? attributes.get("dep", NODEP_LABEL)
                  : null);

  /** A rule which always depends on the given label. */
  private static final MockRule NORMAL_DEPENDER =
      () -> MockRule.define("normal_dep", attr("dep", LABEL).allowedFileTypes());

  /** A rule which depends on a given label only if the given define is set. */
  private static final MockRule LATE_BOUND_DEPENDER =
      () ->
          MockRule.define(
              "late_bound_dep",
              attr("define", STRING).mandatory(),
              attr("dep", NODEP_LABEL).mandatory(),
              attr(":late_bound_dep", LABEL).value(LATE_BOUND_DEP));

  /** A rule which removes a define from the configuration of its dependency. */
  private static final MockRule DEFINE_CLEARER =
      () ->
          MockRule.define(
              "define_clearer",
              attr("define", STRING).mandatory(),
              attr("dep", LABEL)
                  .mandatory()
                  .allowedFileTypes()
                  .cfg(
                      new TransitionFactory<AttributeTransitionData>() {
                        @Override
                        public SplitTransition create(AttributeTransitionData data) {
                          return (BuildOptions options) -> {
                            String define = data.attributes().get("define", STRING);
                            BuildOptions newOptions = options.clone();
                            CoreOptions optionsFragment = newOptions.get(CoreOptions.class);
                            optionsFragment.commandLineBuildVariables =
                                optionsFragment.commandLineBuildVariables.stream()
                                    .filter((pair) -> !pair.getKey().equals(define))
                                    .collect(toImmutableList());
                            return ImmutableList.of(newOptions);
                          };
                        }

                        @Override
                        public boolean isSplit() {
                          return true;
                        }
                      }));

  @Override
  protected ConfiguredRuleClassProvider getRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder =
        new ConfiguredRuleClassProvider.Builder()
            .addRuleDefinition(NORMAL_DEPENDER)
            .addRuleDefinition(LATE_BOUND_DEPENDER)
            .addRuleDefinition(DEFINE_CLEARER);
    TestRuleClassProvider.addStandardRules(builder);
    return builder.build();
  }

  @Test
  public void testLateBoundTargetCycleNotConfiguredTargetCycle() throws Exception {
    // Target graph: //a -> //b -?> //c -> //a (loop)
    // Configured target graph: //a -> //b -> //c -> //a (2) -> //b (2)
    scratch.file("a/BUILD", "normal_dep(name = 'a', dep = '//b')");
    scratch.file("b/BUILD", "late_bound_dep(name = 'b', dep = '//c', define = 'CYCLE_ON')");
    scratch.file("c/BUILD", "define_clearer(name = 'c', dep = '//a', define = 'CYCLE_ON')");

    useConfiguration("--define=CYCLE_ON=yes");
    getConfiguredTarget("//a");
    assertNoEvents();
  }

  @Test
  public void testSelectTargetCycleNotConfiguredTargetCycle() throws Exception {
    // Target graph: //a -> //b -?> //c -> //a (loop)
    // Configured target graph: //a -> //b -> //c -> //a (2) -> //b (2) -> //b:stop (2)
    scratch.file("a/BUILD", "normal_dep(name = 'a', dep = '//b')");
    scratch.file("b/BUILD",
        "config_setting(name = 'cycle', define_values = {'CYCLE_ON': 'yes'})",
        "normal_dep(name = 'stop')",
        "normal_dep(name = 'b', dep = select({':cycle': '//c', '//conditions:default': ':stop'}))");
    scratch.file("c/BUILD", "define_clearer(name = 'c', dep = '//a', define = 'CYCLE_ON')");

    useConfiguration("--define=CYCLE_ON=yes");
    getConfiguredTarget("//a");
    assertNoEvents();
  }
}
