// Copyright 2016 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.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.bazel.LicenseCheckingModule;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.packages.License;
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.License.LicenseParsingException;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.util.MockCcSupport;
import com.google.devtools.build.lib.syntax.Type;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Integration tests for {@link License}.
 */
@RunWith(JUnit4.class)
public class LicensingTests extends BuildViewTestCase {

  /** Filter to remove implicit dependencies of sh_* rules. */
  private static final Predicate<String> SH_LABEL_NAME_FILTER = new Predicate<String>() {
    @Override
    public boolean apply(String label) {
      return !label.startsWith("//util/shell/");
      }
  };

  private static final Predicate<Label> SH_LABEL_FILTER = new Predicate<Label>() {
    @Override
    public boolean apply(Label label) {
      return SH_LABEL_NAME_FILTER.apply("//" + label.getPackageName());
    }
  };


  /** Filter to remove implicit dependencies of Java rules. */
  private static final Predicate<String> JAVA_LABEL_NAME_FILTER = new Predicate<String>() {
    @Override
    public boolean apply(String label) {
      return !label.startsWith("//third_party/java/jdk");
    }
  };

  public static final Predicate<Label> JAVA_LABEL_FILTER = new Predicate<Label>() {
    @Override
    public boolean apply(Label label) {
      return JAVA_LABEL_NAME_FILTER.apply("//" + label.getPackageName());
    }
  };

  @SuppressWarnings("unchecked")
  public static final Predicate<Label> CC_OR_JAVA_OR_SH_LABEL_FILTER =
      Predicates.and(
          AnalysisMock.get().ccSupport().labelFilter(),
          JAVA_LABEL_FILTER,
          SH_LABEL_FILTER);

  @Before
  public final void useCorrectConfiguration() throws Exception {
    useConfiguration("--check_licenses");
  }

  @Test
  public void testCollectDistribs() throws Exception {
    scratch.file("a/BUILD",
        "distribs(['client', 'web'])",
        "cc_library(name = 'alib', srcs=['a.cc'], deps=[':blib'])",
        "cc_library(name = 'blib', distribs=['client'])");
    scratch.file("kaboom/BUILD",
        "cc_library(name = 'boom', srcs=['bang.cc'])");
    assertThat(getTarget("//a:alib").getDistributions())
        .containsExactlyElementsIn(
            Sets.newHashSet(License.DistributionType.CLIENT, License.DistributionType.WEB));
    assertThat(getTarget("//a:blib").getDistributions())
        .containsExactlyElementsIn(Sets.newHashSet(License.DistributionType.CLIENT));
    assertThat(getTarget("//kaboom:boom").getDistributions())
        .containsExactlyElementsIn(Sets.newHashSet(License.DistributionType.INTERNAL));
  }

  // Same test, using package.distribs.
  @Test
  public void testCollectDistribsPackage() throws Exception {
    scratch.file("a/BUILD",
        "package(distribs = ['client', 'web'])",
        "cc_library(name = 'alib', srcs=['a.cc'], deps=[':blib'])",
        "cc_library(name = 'blib', distribs=['client'])");
    scratch.file("kaboom/BUILD",
        "cc_library(name = 'boom', srcs=['bang.cc'])");
    assertThat(getTarget("//a:alib").getDistributions())
        .containsExactlyElementsIn(
            Sets.newHashSet(License.DistributionType.CLIENT, License.DistributionType.WEB));
    assertThat(getTarget("//a:blib").getDistributions())
        .containsExactlyElementsIn(Sets.newHashSet(License.DistributionType.CLIENT));
    assertThat(getTarget("//kaboom:boom").getDistributions())
        .containsExactlyElementsIn(Sets.newHashSet(License.DistributionType.INTERNAL));
  }

  // Test for package.licenses
  @Test
  public void testCollectLicensesPackage() throws Exception {
    scratch.file("a/BUILD",
        "licenses(['restricted', 'reciprocal'])",
        "exports_files(['a'])");

    ConfiguredTarget target = getConfiguredTarget("//a:a");
    License license = getTarget(target.getLabel()).getLicense();
    assertThat(license).isEqualTo(License.parseLicense(Arrays.asList("restricted", "reciprocal")));
  }

  @Test
  public void testCollectLicenses() throws Exception {
    Predicate<Label> SOURCE_FILTER =
        new Predicate<Label>() {
          @Override
          public boolean apply(Label label) {
            // Remove source files from the results.
            return AnalysisMock.get().ccSupport().labelFilter().apply(label)
                && !label.toString().endsWith(".cc");
          }
        };

    scratch.file("a/BUILD",
        "licenses(['restricted', 'reciprocal'])",
        "cc_library(name = 'alib', srcs=['a.cc'], deps=[':blib'])",
        "cc_library(name = 'blib', srcs=['b.cc'], distribs=['web'], "
        + "deps=['//kaboom:boom', '//kablam:blam'])",
        "exports_files(['c'])");
    scratch.file("kaboom/BUILD",
        "licenses(['notice'])",
        "cc_library(name = 'boom', srcs=['bang.cc'])");
    scratch.file("kablam/BUILD",
        "licenses(['restricted','exception=//a:alib'])",
        "cc_library(name='blam', srcs=['blam.cc'])");
    ConfiguredTarget aTarget = getConfiguredTarget("//a:alib");
    ConfiguredTarget bTarget = getConfiguredTarget("//a:blib");
    ConfiguredTarget cTarget = getConfiguredTarget("//a:c");
    ConfiguredTarget kaboomTarget = getConfiguredTarget("//kaboom:boom");
    ConfiguredTarget kablamTarget = getConfiguredTarget("//kablam:blam");
    Map<Label, License> aMap =
        Maps.filterKeys(getTransitiveLicenses(aTarget), SOURCE_FILTER);
    Map<Label, License> aExpected = licenses("//a:alib", "restricted,reciprocal",
                                             "//a:blib", "restricted,reciprocal",
                                             "//kablam:blam", "restricted,exception=//a:alib",
                                             "//kaboom:boom", "notice");
    assertSameMapEntries(aExpected, aMap);

    Map<Label, License> bMap =
        Maps.filterKeys(getTransitiveLicenses(bTarget), SOURCE_FILTER);
    Map<Label, License> bExpected = licenses("//a:blib", "restricted,reciprocal",
                                             "//kablam:blam", "restricted,exception=//a:alib",
                                             "//kaboom:boom", "notice");
    assertSameMapEntries(bExpected, bMap);

    Map<Label, License> kaboomMap =
        Maps.filterKeys(getTransitiveLicenses(kaboomTarget), SOURCE_FILTER);
    assertSameMapEntries(
        licenses("//kaboom:boom", "notice"),
        kaboomMap);

    Map<Label, License> kablamMap =
        Maps.filterKeys(getTransitiveLicenses(kablamTarget), SOURCE_FILTER);
    assertSameMapEntries(
        licenses("//kablam:blam", "restricted,exception=//a:alib"),
        kablamMap);

    License cLicense = getTarget(cTarget.getLabel()).getLicense();
    assertThat(cLicense).isEqualTo(License.parseLicense(Arrays.asList("restricted", "reciprocal")));
  }

  @Test
  public void testClientLicenseOverridesDefault() throws Exception {
    scratch.file("a/BUILD",
        "licenses(['restricted', 'reciprocal'])",
        "cc_library(name = 'alib', srcs=['a.cc'], deps=[':blib'], licenses=['unencumbered'])",
        "cc_library(name = 'blib', srcs=['b.cc'], distribs=['web'])",
        "exports_files(['c'], licenses = ['unencumbered'])");
    ConfiguredTarget aTarget = getConfiguredTarget("//a:alib");
    ConfiguredTarget bTarget = getConfiguredTarget("//a:blib");
    ConfiguredTarget cTarget = getConfiguredTarget("//a:c");
    License aLicense = getTarget(aTarget.getLabel()).getLicense();
    License bLicense = getTarget(bTarget.getLabel()).getLicense();
    License cLicense = getTarget(cTarget.getLabel()).getLicense();
    assertThat(aLicense.equals(bLicense)).isFalse();
    assertThat(aLicense).isEqualTo(License.parseLicense(Arrays.asList("unencumbered")));
    assertThat(bLicense).isEqualTo(License.parseLicense(Arrays.asList("restricted", "reciprocal")));
    assertThat(cLicense).isEqualTo(License.parseLicense(Arrays.asList("unencumbered")));
  }

  @Test
  public void testNoneLicenseHandledCorrectly() throws Exception {
    scratch.file("music/BUILD",
        "sh_binary(name='piano', srcs=['piano.sh'], licenses=['none'])");
    Map<Label, License> licenses = Maps.filterKeys(
        getTransitiveLicenses(getConfiguredTarget("//music:piano")),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);
    assertThat(licenses).isEmpty();
  }

  @Test
  public void testToolLicenseAddedCorrectly() throws Exception {
    scratch.file("powertools/BUILD",
        "sh_binary(name = 'chainsaw',",
        "          srcs = ['chainsaw.sh'],",
        "          licenses=['restricted'],",
        "          output_licenses=['unencumbered'])");

    scratch.file("gr/BUILD",
        "licenses(['unencumbered'])",
        "genrule(name = 'lumberjack',",
        "        outs=['firewood'],",
        "        tools=['//powertools:chainsaw'],",
        "        cmd='')",
        "genrule(name = 'xorn',",
        "        outs=['jewel'],",
        "        srcs=['//powertools:chainsaw'],",
        "        cmd='')");

    ConfiguredTarget lumberjack = getConfiguredTarget("//gr:lumberjack");
    ConfiguredTarget xorn = getConfiguredTarget("//gr:xorn");
    Map<Label, License> lumberjackActual = Maps.filterKeys(getTransitiveLicenses(lumberjack),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);
    Map<Label, License> xornActual = Maps.filterKeys(getTransitiveLicenses(xorn),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);

    Map<Label, License> lumberjackExpected = licenses(
        "//powertools:chainsaw", "unencumbered",
        "//gr:lumberjack", "unencumbered");
    Map<Label, License> xornExpected = licenses(
        "//powertools:chainsaw", "restricted",
        "//gr:xorn", "unencumbered");

    assertSameMapEntries(lumberjackExpected, lumberjackActual);
    assertSameMapEntries(xornExpected, xornActual);
  }

  @Test
  public void testToolLicenseDoesNotIncludeDependencies() throws Exception {
    scratch.file("powertools/BUILD",
        "sh_binary(name = 'chainsaw',",
        "          srcs = ['chainsaw.sh'],",
        "          deps = [':gasoline'],",
        "          licenses = ['restricted'],",
        "          output_licenses=['unencumbered'])",
        "sh_binary(name = 'gasoline',",
        "          srcs = ['gasoline.sh'],",
        "          licenses = ['notice'])");

    scratch.file("gr/BUILD",
        "licenses(['unencumbered'])",
        "genrule(name = 'lumberjack',",
        "        outs=['firewood'],",
        "        tools=['//powertools:chainsaw'],",
        "        cmd='')");

    ConfiguredTarget lumberjack = getConfiguredTarget("//gr:lumberjack");
    Map<Label, License> actual = Maps.filterKeys(getTransitiveLicenses(lumberjack),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);

    Map<Label, License> expected = licenses(
        "//powertools:chainsaw", "unencumbered",
        "//gr:lumberjack", "unencumbered");

    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testFilegroupAllowsOutputLicenseDeclaration() throws Exception {
    scratch.file("apple/BUILD",
        "licenses(['restricted'])",
        "filegroup(name='apples',",
        "          output_licenses=['unencumbered'],",
        "          srcs=['rambo', 'granny_smith'])");

    scratch.file("apfelmuss/BUILD",
        "licenses(['unencumbered'])",
        "genrule(name = 'apfelmuss',",
        "        outs = ['jar'],",
        "        tools = ['//apple:apples'],",
        "        cmd = 'magic')");

    ConfiguredTarget apfelmuss = getConfiguredTarget("//apfelmuss:apfelmuss");
    Map<Label, License> actual = Maps.filterKeys(getTransitiveLicenses(apfelmuss),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);
    Map<Label, License> expected = licenses(
        "//apfelmuss:apfelmuss", "unencumbered",
        "//apple:apples", "unencumbered");

    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testEmptyToolLicenseWorks() throws Exception {
    scratch.file("powertools/BUILD",
        "sh_binary(name = 'chainsaw',",
        "          srcs = ['chainsaw.sh'],",
        "          deps = [':gasoline'],",
        "          licenses = ['restricted'],",
        "          output_licenses=[])",
        "sh_binary(name = 'gasoline',",
        "          srcs = ['gasoline.sh'],",
        "          licenses = ['notice'])");

    scratch.file("gr/BUILD",
        "genrule(name = 'lumberjack',",
        "        outs=['firewood'],",
        "        tools=['//powertools:chainsaw'],",
        "        cmd='')");

    ConfiguredTarget lumberjack = getConfiguredTarget("//gr:lumberjack");
    Map<Label, License> actual = Maps.filterKeys(getTransitiveLicenses(lumberjack),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);

    Map<Label, License> expected = licenses("//powertools:chainsaw", "");
    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testToolLicenseIncludesDependenciesIfNoOutputLicense() throws Exception {
    scratch.file("powertools/BUILD",
        "sh_binary(name = 'chainsaw',",
        "          srcs = ['chainsaw.sh'],",
        "          deps = [':gasoline'],",
        "          licenses = ['restricted'])",
        "sh_binary(name = 'gasoline',",
        "          srcs = ['gasoline.sh'],",
        "          licenses = ['notice'])");

    scratch.file("gr/BUILD",
        "licenses(['unencumbered'])",
        "genrule(name = 'lumberjack',",
        "        outs=['firewood'],",
        "        tools=['//powertools:chainsaw'],",
        "        cmd='')");

    ConfiguredTarget lumberjack = getConfiguredTarget("//gr:lumberjack");
    Map<Label, License> actual = Maps.filterKeys(getTransitiveLicenses(lumberjack),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);

    Map<Label, License> expected = licenses(
        "//powertools:chainsaw", "restricted",
        "//powertools:gasoline", "notice",
        "//gr:lumberjack", "unencumbered");

    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testToolLicenseRecursively() throws Exception {
    scratch.file("powertools/BUILD",
        "licenses(['restricted'])",
        "filegroup(name = 'chainsaw',",
        "          srcs = ['chainsaw.sh'],",
        "          licenses=['restricted'],",
        "          output_licenses=['unencumbered'])",
        "filegroup(name = 'forward',",
        "          srcs = [':chainsaw'])");

    scratch.file("gr/BUILD",
        "licenses(['unencumbered'])",
        "genrule(name = 'lumberjack',",
        "        outs=['firewood'],",
        "        tools=['//powertools:forward'],",
        "        cmd='')");

    ConfiguredTarget lumberjack = getConfiguredTarget("//gr:lumberjack");
    Map<Label, License> lumberjackActual = Maps.filterKeys(getTransitiveLicenses(lumberjack),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);

    Map<Label, License> lumberjackExpected = licenses(
        "//powertools:chainsaw", "unencumbered",
        "//powertools:forward", "restricted",
        "//gr:lumberjack", "unencumbered");

    assertSameMapEntries(lumberjackExpected, lumberjackActual);
  }

  @Test
  public void testHostAttributeCanBeTool() throws Exception {
    scratch.file(
        "test/BUILD",
        "genrule(",
        "    name='gen',",
        "    outs=['hello.txt'],",
        "    cmd='exit 1',",
        "    tools=['//test:compiler'],",
        ")",
        "sh_binary(",
        "    name='compiler',",
        "    srcs=['compiler.sh'],",
        "    licenses=['restricted'],",
        "    output_licenses=['notice'],",
        ")");

    ConfiguredTarget target = getConfiguredTarget("//test:gen");
    Map<Label, License> actual = Maps.filterKeys(getTransitiveLicenses(target),
        CC_OR_JAVA_OR_SH_LABEL_FILTER);
    Map<Label, License> expected = licenses("//test:compiler", "notice");
    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testNonHostAttributeCannotBeTool() throws Exception {
    scratch.file("keyboardmonkeys/BUILD",
        "genrule(name='million_monkeys',",
        "        licenses=['restricted'],",
        "        output_licenses=['notice'],",
        "        outs=['source.sh'],",
        "        cmd='type furiously on typewriters')");

    scratch.file("product/BUILD",
        "sh_binary(name='product',",
        "          srcs=['//keyboardmonkeys:source.sh'])");

    ConfiguredTarget product = getConfiguredTarget("//product:product");
    Map<Label, License> actual = Maps.filterKeys(
            getTransitiveLicenses(product), CC_OR_JAVA_OR_SH_LABEL_FILTER);

    Map<Label, License> expected = licenses("//keyboardmonkeys:million_monkeys", "restricted");
    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testCcToolchainLicenseOverride() throws Exception {
    scratch.file(
        "c/BUILD",
        "filegroup(name = 'dynamic-runtime-libs-cherry', srcs = [], licenses = ['restricted'])",
        "cc_toolchain(",
        "    name = 'c',",
        "    toolchain_identifier = 'toolchain-identifier-k8',",
        "    output_licenses = ['notice'],",
        "    ar_files = 'ar-cherry',",
        "    as_files = 'as-cherry',",
        "    compiler_files = 'compile-cherry',",
        "    dwp_files = 'dwp-cherry',",
        "    coverage_files = 'gcov-cherry',",
        "    linker_files = 'link-cherry',",
        "    strip_files = ':every-file',",
        "    objcopy_files = 'objcopy-cherry',",
        "    all_files = ':every-file',",
        "    dynamic_runtime_lib = 'dynamic-runtime-libs-cherry',",
        "    static_runtime_lib = 'static-runtime-libs-cherry')");
    scratch.file("c/CROSSTOOL", MockCcSupport.EMPTY_CROSSTOOL);

    ConfiguredTarget target = getConfiguredTarget("//c:c");
    Map<Label, License> expected = licenses("//c:c", "notice");
    Map<Label, License> actual = getTransitiveLicenses(target);
    assertSameMapEntries(expected, actual);
  }

  @Test
  public void testLicenseParsing() throws Exception {
    License l1 = License.parseLicense(Arrays.asList("restricted",
        "exception=//a:a"));
    License l2 = License.parseLicense(Arrays.asList("restricted",
        "reciprocal", "exception=//a:a"));
    License l3 = License.parseLicense(Arrays.asList("by_exception_only",
        "reciprocal", "exception=//a:a", "exception=//b:b"));
    assertThat(l1.toString()).isEqualTo("[restricted] with exceptions [//a:a]");
    assertThat(l2.toString()).isEqualTo("[restricted, reciprocal] with exceptions [//a:a]");
    assertThat(l3.toString())
        .isEqualTo("[by_exception_only, reciprocal] with exceptions [//a:a, //b:b]");
  }

  /**
   * Takes a list of strings, which alternate labels with license lists, and
   * returns a map of labels to licenses. The license strings are comma-separated
   * strings.
   */
  protected static Map<Label, License> licenses(String... strings)
      throws LicenseParsingException, LabelSyntaxException {
    Map<Label, License> result = new HashMap<>();
    for (int i = 0; i < strings.length; i += 2) {
      String labelStr = strings[i];
      String licStr = strings[i + 1];
      Label label = Label.parseAbsolute(labelStr, ImmutableMap.of());
      List<String> splitLicenses =
          licStr.isEmpty() ? Arrays.<String>asList() : Arrays.asList(licStr.split(","));
      License license = License.parseLicense(splitLicenses);
      result.put(label, license);
    }
    return result;
  }

  protected static<K, V> void assertSameMapEntries(Map<K, V> expected, Map<K, V> actual) {
    if (expected.size() != actual.size()) {
      StringBuilder actualString = new StringBuilder();
      for (K key : actual.keySet()) {
        actualString.append(key + ": " + actual.get(key) + "\n");
      }
      int expectedSize = expected.size();
      assertWithMessage("Expected map of size '%s' but found map of size '%s', actual value:\n%s",
          expectedSize, actual.size(), actualString)
          .that(actual)
          .hasSize(expectedSize);
    }
    for (K key : expected.keySet()) {
      V expectedValue = expected.get(key);
      V actualValue = actual.get(key);
      assertWithMessage("Key '%s'", key).that(actualValue).isNotNull();
      assertWithMessage("Values for key '" + key + "' should match")
          .that(actualValue)
          .isEqualTo(expectedValue);
    }
  }

  @Test
  public void testDualLicensedUsesLeastRestrictive() throws Exception {
    scratch.file("user/BUILD",
        "sh_binary(name = 'user',",
        "          srcs = ['user.sh'],",
        "          deps = ['//used'])");

    scratch.file("used/BUILD",
        "licenses(['restricted', 'permissive'])",
        "sh_library(name = 'used',",
        "        srcs=['used.sh'])");

    ConfiguredTarget used = getConfiguredTarget("//used");
    Map<Label, License> usedActual =
        Maps.filterKeys(getTransitiveLicenses(used), AnalysisMock.get().ccSupport().labelFilter());
    Label usedLabel = Label.parseAbsolute("//used", ImmutableMap.of());
    License license = usedActual.get(usedLabel);
    LicenseCheckingModule.checkCompatibility(
        license,
        EnumSet.of(DistributionType.CLIENT),
        getTarget("//user"),
        usedLabel,
        reporter,
        false);
    assertNoEvents();
  }

  /** Regression test for b/9811855. */
  @Test
  public void testFilegroupLicenses() throws Exception {
    scratch.file("user/BUILD",
        "sh_binary(name = 'user',",
        "          srcs = ['user.sh'],",
        "          deps = ['//used'])");

    scratch.file("used/BUILD",
        "licenses(['restricted'])",
        "filegroup(name = 'used',",
        "        licenses=['unencumbered'],",
        "        srcs=['used.sh'])"); // used.sh is not 'restricted'

    ConfiguredTarget used = getConfiguredTarget("//used");
    Map<Label, License> usedActual =
        Maps.filterKeys(getTransitiveLicenses(used), AnalysisMock.get().ccSupport().labelFilter());
    Label usedLabel = Label.parseAbsolute("//used", ImmutableMap.of());
    License license = usedActual.get(usedLabel);
    LicenseCheckingModule.checkCompatibility(
        license,
        EnumSet.of(DistributionType.CLIENT),
        getTarget("//user"),
        usedLabel,
        reporter,
        false);
    assertNoEvents();
  }

  /**
   * Regression test for b/4159051: "Latest blaze release broke --check_licenses"
   */
  @Test
  public void testLicenseCheckingTakesOnlyOneSelectBranch() throws Exception {
    scratch.file("eden/BUILD",
        "config_setting(",
        "    name = 'config_a',",
        "    values = {'define': 'mode=a'})",
        "cc_library(name = 'eve',",
        "    deps = select({",
        "        ':config_a': ['//third_party/fruit:peach'],",
        "        '//conditions:default': ['//third_party/fruit:apple'],",
        "    }),",
        "    distribs = ['client'])");

    scratch.file("third_party/fruit/BUILD",
        "cc_library(name='apple', licenses=['restricted'])",
        "cc_library(name='peach', licenses=['unencumbered'])");

    useConfiguration("--check_licenses", "--define", "mode=a");
    ConfiguredTarget eve = getConfiguredTarget("//eden:eve");
    Map<Label, License> eveActual =
        Maps.filterKeys(getTransitiveLicenses(eve), AnalysisMock.get().ccSupport().labelFilter());
    Map<Label, License> eveExpected = licenses("//third_party/fruit:peach", "unencumbered");
    assertSameMapEntries(eveExpected, eveActual);
    assertNoEvents();
  }

  @Test
  public void configSettingsHaveNoLicense() throws Exception {
    scratch.file("third_party/restricted/BUILD",
        "licenses(['by_exception_only'])",
        "config_setting(",
        "    name = 'a_setting',",
        "    values = {'define': 'mode=a'})");
    useConfiguration("--check_licenses", "--define", "mode=a");
    ConfiguredTarget configSetting = getConfiguredTarget("//third_party/restricted:a_setting");
    assertThat(configSetting.getProvider(LicensesProvider.class).getTransitiveLicenses())
        .isEmpty();
  }

  @Ignore("b/129599508")
  @Test
  public void testJavaToolchainOutputLicense() throws Exception {
    scratch.file("java/a/BUILD",
        "java_toolchain(",
        "  name = 'toolchain',",
        "  licenses = ['restricted'],",
        "  output_licenses = ['unencumbered'],",
        "  source_version = '8',",
        "  target_version = '8',",
        "  bootclasspath = [':bcp'],",
        "  extclasspath = [':ecp'],",
        "  javac = [':langtools'],",
        "  javabuilder = ['javabuilder'],",
        "  header_compiler = ['header_compiler'],",
        "  singlejar = ['singlejar'],",
        "  genclass = ['genclass'],",
        "  ijar = ['ijar'])",
        "java_binary(",
        "  name = 'a',",
        "  srcs = ['a.java'])");

    useConfiguration("--java_toolchain=//java/a:toolchain", "--check_licenses");

    ConfiguredTarget bin = getConfiguredTarget("//java/a:a");
    Map<Label, License> licenses = getTransitiveLicenses(bin);
    License toolchainLicense = licenses.get(Label.parseAbsoluteUnchecked("//java/a:toolchain"));
    assertThat(toolchainLicense).isNotEqualTo(License.parseLicense(ImmutableList.of("restricted")));
    assertThat(toolchainLicense).isEqualTo(License.parseLicense(ImmutableList.of("unencumbered")));
  }

  @Test
  public void testTargetLicenseEquality() throws Exception {
    Label label1 = Label.parseAbsolute("//foo", ImmutableMap.of());
    Label label2 = Label.parseAbsolute("//bar", ImmutableMap.of());
    License restricted = License.parseLicense(ImmutableList.of("restricted"));
    License unencumbered = License.parseLicense(ImmutableList.of("unencumbered"));
    new EqualsTester()
        .addEqualityGroup(
            new TargetLicense(label1, restricted),
            new TargetLicense(label1, restricted))
        .addEqualityGroup(
            new TargetLicense(label2, restricted),
            new TargetLicense(label2, restricted))
        .addEqualityGroup(
            new TargetLicense(label2, unencumbered),
            new TargetLicense(label2, unencumbered))
        .testEquals();
  }

  /** Regression fix for https://github.com/bazelbuild/bazel/issues/7194. */
  @Test
  public void testStarlarkLicensesAttributeCanUseUseCustomDefault() throws Exception {
    scratch.file(
        "foo/rules.bzl",
        "def _myrule_impl(ctx):",
        "    return []",
        "",
        "myrule = rule(",
        "    implementation = _myrule_impl,",
        "    attrs = {",
        "        'licenses': attr.string(default = 'custom_licenses_default'),",
        "    }",
        ")");

    scratch.file("foo/BUILD", "load('//foo:rules.bzl', 'myrule')", "myrule(name = 'hi')");

    assertThat(RawAttributeMapper.of((Rule) getTarget("//foo:hi")).get("licenses", Type.STRING))
        .isEqualTo("custom_licenses_default");
    assertNoEvents();
  }

  /**
   * Gets the licenses of all targets that are in the transitive closure of a
   * target. The result includes this target itself.
   *
   * @return a map from target labels to licenses
   */
  protected static Map<Label, License> getTransitiveLicenses(ConfiguredTarget target) {
    final ImmutableMap.Builder<Label, License> result = ImmutableMap.builder();
    LicensesProvider provider = target.getProvider(LicensesProvider.class);
    if (provider != null) {
      for (TargetLicense targetLicense : provider.getTransitiveLicenses()) {
        result.put(targetLicense.getLabel(), targetLicense.getLicense());
      }
    }

    return result.build();
  }
}
