// Copyright 2019 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.packages;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for ensuring that optimizations we have during package loading actually occur. */
@RunWith(JUnit4.class)
public class PackageLoadingOptimizationsTest extends PackageLoadingTestCase {
  @Test
  public void attributeListValuesAreDedupedIntraPackage() throws Exception {
    scratch.file(
        "foo/BUILD",
        "L = ['//other:t' + str(i) for i in range(10)]",
        "[sh_library(name = 't' + str(i), deps = L) for i in range(10)]");

    Package fooPkg =
        getPackageManager()
            .getPackage(NullEventHandler.INSTANCE, PackageIdentifier.createInMainRepo("foo"));

    ImmutableList.Builder<ImmutableList<Label>> allListsBuilder = ImmutableList.builder();
    for (Rule ruleInstance : fooPkg.getTargets(Rule.class)) {
      assertThat(ruleInstance.getTargetKind()).isEqualTo("sh_library rule");
      @SuppressWarnings("unchecked")
      ImmutableList<Label> depsList =
          (ImmutableList<Label>) ruleInstance.getAttributeContainer().getAttr("deps");
      allListsBuilder.add(depsList);
    }
    ImmutableList<ImmutableList<Label>> allLists = allListsBuilder.build();
    assertThat(allLists).hasSize(10);
    ImmutableList<Label> firstList = allLists.get(0);
    for (int i = 1; i < allLists.size(); i++) {
      assertThat(allLists.get(i)).isSameInstanceAs(firstList);
    }
  }

  @Test
  public void testRuntimeListValueIsDedupedAcrossRuleClasses() throws Exception {
    scratch.file(
        "foo/foo.bzl",
        "def _foo_test_impl(ctx):",
        "  return",
        "foo_test = rule(implementation = _foo_test_impl, test = True)");
    scratch.file(
        "foo/BUILD",
        "load(':foo.bzl', 'foo_test')",
        "[sh_test(name = str(i) + '_test', srcs = ['t.sh']) for i in range(5)]",
        "[foo_test(name = str(i) + '_foo_test') for i in range(5)]");

    Package fooPkg =
        getPackageManager()
            .getPackage(NullEventHandler.INSTANCE, PackageIdentifier.createInMainRepo("foo"));

    ImmutableList.Builder<ImmutableList<Label>> allListsBuilder = ImmutableList.builder();
    for (Rule ruleInstance : fooPkg.getTargets(Rule.class)) {
      assertThat(ruleInstance.getTargetKind()).endsWith("_test rule");
      @SuppressWarnings("unchecked")
      ImmutableList<Label> testRuntimeList =
          (ImmutableList<Label>) ruleInstance.getAttributeContainer().getAttr("$test_runtime");
      allListsBuilder.add(testRuntimeList);
    }
    ImmutableList<ImmutableList<Label>> allLists = allListsBuilder.build();
    assertThat(allLists).hasSize(10);
    ImmutableList<Label> firstList = allLists.get(0);
    for (int i = 1; i < allLists.size(); i++) {
      assertThat(allLists.get(i)).isSameInstanceAs(firstList);
    }
  }

  @Test
  public void skylarkProviderIdentifierIsDedupedAcrossRuleClasses() throws Exception {
    scratch.file("foo/provider.bzl", "foo_provider = provider()");
    scratch.file(
        "foo/foo.bzl",
        "load(':provider.bzl', 'foo_provider')",
        "def _foo_impl(ctx):",
        "  return",
        "foo_rule = rule(implementation = _foo_impl, provides=[foo_provider])");
    scratch.file(
        "foo/foobar.bzl",
        "load(':provider.bzl', 'foo_provider')",
        "def _foobar_impl(ctx):",
        "  return",
        "foobar_rule = rule(implementation = _foobar_impl, provides=[foo_provider])");
    scratch.file(
        "foo/BUILD",
        "load(':foo.bzl', 'foo_rule')",
        "load(':foobar.bzl', 'foobar_rule')",
        "foo_rule(name = 'foo_rule_instance')",
        "foobar_rule(name = 'foobar_rule_instance')");

    Package fooPkg =
        getPackageManager()
            .getPackage(NullEventHandler.INSTANCE, PackageIdentifier.createInMainRepo("foo"));

    ImmutableList.Builder<ImmutableList<SkylarkProviderIdentifier>> allListsBuilder =
        ImmutableList.builder();
    for (Rule ruleInstance : fooPkg.getTargets(Rule.class)) {
      RuleClass ruleClass = ruleInstance.getRuleClassObject();
      allListsBuilder.add(ruleClass.getAdvertisedProviders().getSkylarkProviders().asList());
    }
    ImmutableList<ImmutableList<SkylarkProviderIdentifier>> allLists = allListsBuilder.build();
    assertThat(allLists).hasSize(2);
    ImmutableList<SkylarkProviderIdentifier> firstList = allLists.get(0);
    for (int i = 1; i < allLists.size(); i++) {
      assertThat(allLists.get(i).get(0)).isSameInstanceAs(firstList.get(0));
    }
  }

  @Test
  public void testSuiteImplicitTestsAttributeValueIsSortedByTargetName() throws Exception {
    // When we have a BUILD file that instantiates some test targets
    scratch.file(
        "foo/BUILD",
        // (in an order that is not target-name-order),
        "sh_test(name = 'bTest', srcs = ['test.sh'])",
        "sh_test(name = 'cTest', srcs = ['test.sh'])",
        "sh_test(name = 'aTest', srcs = ['test.sh'])",
        // And also a `test_suite` target, without setting the `test_suite.tests` attribute,
        "test_suite(name = 'suite')");

    // Then when we load the package,
    PackageIdentifier fooPkgId = PackageIdentifier.createInMainRepo("foo");
    Package fooPkg = getPackageManager().getPackage(NullEventHandler.INSTANCE, fooPkgId);

    // And we get the Rule instance for the `test_suite` target,
    Rule testSuiteRuleInstance = (Rule) fooPkg.getTarget("suite");
    assertThat(testSuiteRuleInstance.getTargetKind()).isEqualTo("test_suite rule");
    @SuppressWarnings("unchecked")
    Collection<Label> implicitTestsAttributeValue =
        (Collection<Label>)
            testSuiteRuleInstance.getAttributeContainer().getAttr("$implicit_tests");
    // The $implicit_tests attribute's value is ordered by target-name.
    assertThat(implicitTestsAttributeValue)
        .containsExactly(
            Label.create(fooPkgId, "aTest"),
            Label.create(fooPkgId, "bTest"),
            Label.create(fooPkgId, "cTest"))
        .inOrder();
  }
}
