// Copyright 2015 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 static com.google.devtools.build.lib.packages.util.TargetDataSubject.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.PackageSpecification.PackageGroupContents;
import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for PackageGroup. */
@RunWith(JUnit4.class)
public class PackageGroupTest extends PackageLoadingTestCase {

  @Test
  public void testDoesNotFailHorribly() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['//random'],",
        ")");
    // Note that, for our purposes, the packages listed in the package_group need not exist.

    getPackageGroup("fruits", "apple");
  }

  // Regression test for: "Package group with empty name causes Blaze exception"
  @Test
  public void testEmptyPackageGroupNameDoesNotThrow() throws Exception {
    scratch.file(
        "strawberry/BUILD", //
        "package_group(",
        "    name = '',",
        "    packages=[],",
        ")");

    reporter.removeHandler(failFastHandler);
    // Call getTarget() directly since getPackageGroup() requires a name.
    getTarget("//strawberry:BUILD");
    assertContainsEvent("package group has invalid name");
  }

  @Test
  public void testAbsolutePackagesWork() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['//vegetables'],",
        ")");

    PackageGroup grp = getPackageGroup("fruits", "apple");
    assertThat(grp.contains(pkgId("vegetables"))).isTrue();
    assertThat(grp.contains(pkgId("fruits/vegetables"))).isFalse();
  }

  @Test
  public void testPackagesWithoutDoubleSlashDoNotWork() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['vegetables'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "apple");
    assertContainsEvent("invalid package name 'vegetables'");
  }

  @Test
  public void testPackagesWithRepositoryDoNotWork() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'banana',",
        "    packages = ['@veggies//:cucumber'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "banana");
    assertContainsEvent("invalid package name '@veggies//:cucumber'");
  }

  @Test
  public void testAllPackagesInMainRepositoryDoesNotWork() throws Exception {
    scratch.file(
        "fruits/BUILD", //
        "package_group(",
        "    name = 'apple',",
        "    packages = ['@//...'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "apple");
    assertContainsEvent("invalid package name '@//...'");
  }

  // TODO(brandjon): It'd be nice to include a test here that you can cross repositories via
  // `includes`: if package_group //:A includes package_group @repo//:B that has "//foo" in its
  // `packages`, then //:A admits package @repo//foo. Unfortunately PackageLoadingTestCase doesn't
  // support resolving repos, but similar functionality is tested in
  // BzlLoadFunctionTest#testBzlVisibility_enumeratedPackagesMultipleRepos.

  @Test
  public void testTargetNameAsPackageDoesNotWork1() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['//vegetables:carrot'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "apple");
    assertContainsEvent("invalid package name '//vegetables:carrot'");
  }

  @Test
  public void testTargetNameAsPackageDoesNotWork2() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = [':carrot'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "apple");
    assertContainsEvent("invalid package name ':carrot'");
  }

  @Test
  public void testAllBeneathSpecificationWorks() throws Exception {
    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'maracuja',",
        "    packages = ['//tropics/...'],",
        ")");

    getPackageGroup("fruits", "maracuja");
  }

  @Test
  public void testNegative() throws Exception {
    scratch.file(
        "test/BUILD",
        "package_group(",
        "    name = 'packages',",
        "    packages = [",
        "        '//one',",
        "        '//two',",
        "        '-//three',",
        "        '-//four',",
        "    ],",
        ")");

    PackageGroup grp = getPackageGroup("test", "packages");
    assertThat(grp.contains(pkgId("one"))).isTrue();
    assertThat(grp.contains(pkgId("two"))).isTrue();
    assertThat(grp.contains(pkgId("three"))).isFalse();
    assertThat(grp.contains(pkgId("four"))).isFalse();
  }

  @Test
  public void testNegative_noSubpackages() throws Exception {
    scratch.file(
        "test/BUILD",
        "package_group(",
        "    name = 'packages',",
        "    packages = [",
        "        '//pkg/...',",
        "        '-//pkg/one',",
        "    ],",
        ")");

    PackageGroup grp = getPackageGroup("test", "packages");
    assertThat(grp.contains(pkgId("pkg"))).isTrue();
    assertThat(grp.contains(pkgId("pkg/one"))).isFalse();
    assertThat(grp.contains(pkgId("pkg/one/two"))).isTrue();
  }

  @Test
  public void testNegative_subpackages() throws Exception {
    scratch.file(
        "test/BUILD",
        "package_group(",
        "    name = 'packages',",
        "    packages = [",
        "        '//pkg/...',",
        "        '-//pkg/one/...',",
        "    ],",
        ")");

    PackageGroup grp = getPackageGroup("test", "packages");
    assertThat(grp.contains(pkgId("pkg"))).isTrue();
    assertThat(grp.contains(pkgId("pkg/one"))).isFalse();
    assertThat(grp.contains(pkgId("pkg/one/two"))).isFalse();
  }

  @Test
  public void testEverythingSpecificationWorks() throws Exception {
    setBuildLanguageOptions("--incompatible_package_group_has_public_syntax=true");

    scratch.file(
        "fruits/BUILD", //
        "package_group(",
        "    name = 'mango',",
        "    packages = ['public'],",
        ")");
    PackageGroup grp = getPackageGroup("fruits", "mango");

    // Assert that we're using the right package spec.
    assertThat(grp.getContainedPackages(/*includeDoubleSlash=*/ true)).containsExactly("public");
    // Assert that this package spec contains packages from both inside and outside the main repo.
    assertThat(grp.contains(pkgId("pkg"))).isTrue();
    assertThat(grp.contains(pkgId("somerepo", "pkg"))).isTrue();
  }

  @Test
  public void testNothingSpecificationWorks() throws Exception {
    setBuildLanguageOptions("--incompatible_package_group_has_public_syntax=true");

    scratch.file(
        "fruits/BUILD", //
        "package_group(",
        "    name = 'mango',",
        "    packages = ['private'],",
        ")");
    PackageGroup grp = getPackageGroup("fruits", "mango");

    // Assert that we're using the right package spec.
    assertThat(grp.getContainedPackages(/*includeDoubleSlash=*/ true)).containsExactly("private");
    assertThat(grp.contains(pkgId("anything"))).isFalse();
  }

  @Test
  public void testPublicPrivateAreNotAccessibleWithoutFlag() throws Exception {
    setBuildLanguageOptions(
        // Flag being tested
        "--incompatible_package_group_has_public_syntax=false",
        // Must also be disabled in order to disable the above
        "--incompatible_fix_package_group_reporoot_syntax=false");

    scratch.file(
        "foo/BUILD", //
        "package_group(",
        "    name = 'grp1',",
        "    packages = ['public'],",
        ")");
    scratch.file(
        "bar/BUILD", //
        "package_group(",
        "    name = 'grp2',",
        "    packages = ['private'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("foo", "grp1");
    assertContainsEvent(
        "Use of \"public\" package specification requires enabling"
            + " --incompatible_package_group_has_public_syntax");
    getPackageGroup("bar", "grp2");
    assertContainsEvent(
        "Use of \"private\" package specification requires enabling"
            + " --incompatible_package_group_has_public_syntax");
  }

  @Test
  public void testRepoRootSubpackagesIsPublic_withoutFlag() throws Exception {
    setBuildLanguageOptions("--incompatible_fix_package_group_reporoot_syntax=false");

    scratch.file(
        "fruits/BUILD", //
        "package_group(",
        "    name = 'mango',",
        "    packages = ['//...'],",
        ")");
    PackageGroup grp = getPackageGroup("fruits", "mango");

    // Use includeDoubleSlash=true to make package spec stringification distinguish AllPackages from
    // AllPackagesBeneath with empty package path.
    assertThat(grp.getContainedPackages(/*includeDoubleSlash=*/ true))
        // Assert that "//..." gave us AllPackages.
        .containsExactly("public");
    assertThat(grp.contains(pkgId("pkg"))).isTrue();
    assertThat(grp.contains(pkgId("somerepo", "pkg"))).isTrue();
  }

  @Test
  public void testRepoRootSubpackagesIsNotPublic_withFlag() throws Exception {
    setBuildLanguageOptions(
        "--incompatible_package_group_has_public_syntax=true",
        "--incompatible_fix_package_group_reporoot_syntax=true");

    scratch.file(
        "fruits/BUILD", //
        "package_group(",
        "    name = 'mango',",
        "    packages = ['//...'],",
        ")");
    PackageGroup grp = getPackageGroup("fruits", "mango");

    // Use includeDoubleSlash=true to make package spec stringification distinguish AllPackages from
    // AllPackagesBeneath with empty package path.
    assertThat(grp.getContainedPackages(/*includeDoubleSlash=*/ true))
        // Assert that "//..." gave us AllPackagesBeneath.
        .containsExactly("//...");
    assertThat(grp.contains(pkgId("pkg"))).isTrue();
    assertThat(grp.contains(pkgId("somerepo", "pkg"))).isFalse();
  }

  @Test
  public void testCannotUseNewRepoRootSyntaxWithoutPublicSyntax() throws Exception {
    setBuildLanguageOptions(
        "--incompatible_package_group_has_public_syntax=false",
        "--incompatible_fix_package_group_reporoot_syntax=true");

    scratch.file(
        "fruits/BUILD", //
        "package_group(",
        "    name = 'mango',",
        "    packages = ['//something'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "mango");
    assertContainsEvent("Cannot use new \"//...\" meaning without allowing new \"public\" syntax.");
  }

  @Test
  public void testNegative_repoRootSubpackages() throws Exception {
    scratch.file(
        "test/BUILD",
        "package_group(",
        "    name = 'packages',",
        "    packages = [",
        "        '//pkg/one',",
        "        '-//...',",
        "    ],",
        ")");

    PackageGroup grp = getPackageGroup("test", "packages");
    assertThat(grp.contains(pkgId("pkg"))).isFalse();
    assertThat(grp.contains(pkgId("pkg/one"))).isFalse();
    assertThat(grp.contains(pkgId("pkg/one/two"))).isFalse();
  }

  @Test
  public void testNegative_public() throws Exception {
    setBuildLanguageOptions("--incompatible_package_group_has_public_syntax=true");

    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['-public'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "apple");
    assertContainsEvent("Cannot negate \"public\" package specification");
  }

  @Test
  public void testNegative_private() throws Exception {
    setBuildLanguageOptions("--incompatible_package_group_has_public_syntax=true");

    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['-private'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getPackageGroup("fruits", "apple");
    assertContainsEvent("Cannot negate \"private\" package specification");
  }

  @Test
  public void testDuplicatePackage() throws Exception {
    scratch.file(
        "test/BUILD",
        "package_group(",
        "    name = 'packages',",
        "    packages = [",
        "        '//one/two',",
        "        '//one/two',",
        "    ],",
        ")");

    PackageGroup grp = getPackageGroup("test", "packages");
    assertThat(grp.contains(pkgId("one/two"))).isTrue();
  }

  @Test
  public void testStringification() throws Exception {
    RepositoryName main = RepositoryName.MAIN;
    RepositoryName other = RepositoryName.create("other");
    PackageGroupContents contents =
        PackageGroupContents.create(
            ImmutableList.of(
                pkgSpec(main, "//a"),
                pkgSpec(main, "//a/b/..."),
                pkgSpec(main, "-//c"),
                pkgSpec(main, "-//c/d/..."),
                pkgSpec(main, "//..."),
                pkgSpec(main, "-//..."),
                pkgSpec(main, "//"),
                pkgSpec(main, "-//"),
                pkgSpec(other, "//z"),
                pkgSpec(other, "//..."),
                pkgSpec(main, "public"),
                pkgSpec(main, "private")));
    assertThat(contents.packageStrings(/* includeDoubleSlash= */ false))
        .containsExactly(
            "a",
            "",
            "@@other//z",
            "a/b/...",
            "//...",
            "@@other//...",
            "-c",
            "-",
            "-c/d/...",
            "-//...",
            "//...", // legacy syntax for public
            "private");
    assertThat(contents.packageStrings(/* includeDoubleSlash= */ true))
        .containsExactly(
            "//a",
            "//a/b/...",
            "-//c",
            "-//c/d/...",
            "//...",
            "-//...",
            "//",
            "-//",
            "@@other//z",
            "@@other//...",
            "public",
            "private");
    assertThat(contents.packageStringsWithDoubleSlashAndWithoutRepository())
        .containsExactly(
            "//a",
            "//a/b/...",
            "-//c",
            "-//c/d/...",
            "//...",
            "-//...",
            "//",
            "-//",
            "//z",
            "//...",
            "public",
            "private");
  }

  @Test
  public void testReduceForSerialization() throws Exception {
    setBuildLanguageOptions("--incompatible_package_group_has_public_syntax=true");

    scratch.file(
        "fruits/BUILD",
        "package_group(",
        "    name = 'apple',",
        "    packages = ['//vegetables'],",
        ")",
        "package_group(",
        "    name = 'mango',",
        "    packages = ['public'],",
        ")");
    PackageGroup grp = getPackageGroup("fruits", "apple");
    assertThat(grp).hasSamePropertiesAs(grp.reduceForSerialization());

    grp = getPackageGroup("fruits", "mango");
    assertThat(grp).hasSamePropertiesAs(grp.reduceForSerialization());
  }

  /** Convenience method for obtaining a PackageSpecification. */
  private PackageSpecification pkgSpec(RepositoryName repository, String spec) throws Exception {
    return PackageSpecification.fromString(
        repository, spec, /*allowPublicPrivate=*/ true, /*repoRootMeansCurrentRepo=*/ true);
  }

  /** Convenience method for obtaining a PackageIdentifier. */
  private PackageIdentifier pkgId(String packageName) throws Exception {
    return PackageIdentifier.createUnchecked(/*repository=*/ "", packageName);
  }

  /** Convenience method for obtaining a PackageIdentifier outside the main repo. */
  private PackageIdentifier pkgId(String repoName, String packageName) throws Exception {
    return PackageIdentifier.createUnchecked(repoName, packageName);
  }

  /** Evaluates and returns the requested package_group target. */
  private PackageGroup getPackageGroup(String pkg, String name) throws Exception {
    return (PackageGroup) getTarget("//" + pkg + ":" + name);
  }
}
