// 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.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.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.streamPackageStrings(/*includeDoubleSlash=*/ false).collect(toImmutableList()))
        .containsExactly(
            "a",
            "a/b/...",
            "-c",
            "-c/d/...",
            "//...",
            "-//...",
            "",
            "-",
            "@other//z",
            "@other//...",
            "//...", // legacy syntax for public
            "private");
    assertThat(
            contents.streamPackageStrings(/*includeDoubleSlash=*/ true).collect(toImmutableList()))
        .containsExactly(
            "//a",
            "//a/b/...",
            "-//c",
            "-//c/d/...",
            "//...",
            "-//...",
            "//",
            "-//",
            "@other//z",
            "@other//...",
            "public",
            "private");
    assertThat(contents.streamPackageStringsWithoutRepository().collect(toImmutableList()))
        .containsExactly(
            "//a",
            "//a/b/...",
            "-//c",
            "-//c/d/...",
            "//...",
            "-//...",
            "//",
            "-//",
            "//z",
            "//...",
            "public",
            "private");
  }

  /** 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);
  }
}
