// 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.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'],",
        "    cpu = 'cherry',",
        "    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();
  }

  @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();
  }
}
