// 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.rules.android;

import static com.google.common.truth.Truth.assertThat;
import static java.util.stream.Collectors.toList;

import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.configuredtargets.FileConfiguredTarget;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.rules.android.databinding.DataBindingV2Provider;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
import com.google.devtools.build.lib.rules.java.JavaCompilationInfoProvider;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.ImportDepsCheckingLevel;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.JavaOutput;
import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
import com.google.devtools.build.lib.rules.java.ProguardSpecProvider;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link com.google.devtools.build.lib.rules.android.AarImport}. */
@RunWith(JUnit4.class)
public class AarImportTest extends AndroidBuildViewTestCase {

  @Before
  public void setup() throws Exception {
    scratch.file(
        "a/BUILD",
        """
        java_import(
            name = "foo_src",
            jars = ["foo-src.jar"],
        )

        aar_import(
            name = "foo",
            aar = "foo.aar",
            srcjar = ":foo_src",
        )

        aar_import(
            name = "baz",
            aar = "baz.aar",
        )

        java_import(
            name = "bar_src",
            jars = ["bar-src.jar"],
        )

        aar_import(
            name = "bar",
            aar = "bar.aar",
            srcjar = ":bar_src",
            exports = [
                ":foo",
                "//java:baz",
            ],
            deps = [":baz"],
        )

        aar_import(
            name = "intermediate",
            aar = "intermediate.aar",
            deps = [":bar"],
        )

        aar_import(
            name = "last",
            aar = "last.aar",
            deps = [":intermediate"],
        )

        android_library(
            name = "library",
            srcs = ["App.java"],
            custom_package = "com.google.arrimport",
            manifest = "AndroidManifest.xml",
            resource_files = ["res/values/values.xml"],
            deps = [":foo"],
        )
        """);
    scratch.file(
        "java/BUILD",
        """
        android_binary(
            name = "app",
            srcs = ["App.java"],
            manifest = "AndroidManifest.xml",
            deps = ["//a:bar"],
        )

        android_library(
            name = "lib",
            exports = ["//a:bar"],
        )

        java_import(
            name = "baz",
            constraints = ["android"],
            jars = ["baz.jar"],
        )
        """);
    getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a");
  }

  @Test
  public void proguardSpecsProvided() throws Exception {
    ConfiguredTarget binaryTarget = getConfiguredTarget("//a:bar");

    NestedSet<Artifact> transitiveProguardSpecs =
        binaryTarget.get(ProguardSpecProvider.PROVIDER).getTransitiveProguardSpecs();

    assertThat(
            transitiveProguardSpecs.toSet().stream()
                .map(Artifact::getRootRelativePathString)
                .collect(Collectors.toSet()))
        .containsExactly(
            "a/_aar/bar/proguard.txt", "a/_aar/foo/proguard.txt", "a/_aar/baz/proguard.txt");
  }

  @Test
  public void testProguardExtractor() throws Exception {
    ConfiguredTarget target = getConfiguredTarget("//a:bar");
    Artifact proguardSpecsAritfact =
        target.get(ProguardSpecProvider.PROVIDER).getTransitiveProguardSpecs().toList().get(0);

    Artifact aarProguardExtractor =
        getDirectPrerequisite(
                target,
                ruleClassProvider.getToolsRepository()
                    + "//tools/android:aar_embedded_proguard_extractor")
            .getProvider(FilesToRunProvider.class)
            .getExecutable();

    assertThat(getGeneratingSpawnAction(proguardSpecsAritfact).getArguments())
        .containsExactly(
            aarProguardExtractor.getExecPathString(),
            "--input_aar",
            "a/bar.aar",
            "--output_proguard_file",
            proguardSpecsAritfact.getExecPathString());
  }

  @Test
  public void aapt2RTxtProvided() throws Exception {
    ConfiguredTarget libTarget = getConfiguredTarget("//a:library");

    NestedSet<Artifact> transitiveCompiledSymbols =
        libTarget.get(AndroidResourcesInfo.PROVIDER).getTransitiveCompiledSymbols();

    assertThat(
            transitiveCompiledSymbols.toSet().stream()
                .map(Artifact::getRootRelativePathString)
                .collect(Collectors.toSet()))
        .containsExactly("a/foo_symbols/symbols.zip", "a/library_symbols/symbols.zip");

    NestedSet<ValidatedAndroidResources> directResources =
        libTarget.get(AndroidResourcesInfo.PROVIDER).getDirectAndroidResources();

    assertThat(directResources.toList()).hasSize(1);

    ValidatedAndroidResources resourceContainer = directResources.toList().get(0);
    assertThat(resourceContainer.getAapt2RTxt()).isNotNull();
  }

  @Test
  public void testResourcesProvided() throws Exception {
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:foo");

    NestedSet<ValidatedAndroidResources> directResources =
        aarImportTarget.get(AndroidResourcesInfo.PROVIDER).getDirectAndroidResources();
    assertThat(directResources.toList()).hasSize(1);

    ValidatedAndroidResources resourceContainer = directResources.toList().get(0);
    assertThat(resourceContainer.getManifest()).isNotNull();

    Artifact resourceTreeArtifact = Iterables.getOnlyElement(resourceContainer.getResources());
    assertThat(resourceTreeArtifact.isTreeArtifact()).isTrue();
    assertThat(resourceTreeArtifact.getExecPathString()).endsWith("_aar/unzipped/resources/foo");

    NestedSet<ParsedAndroidAssets> directAssets =
        aarImportTarget.get(AndroidAssetsInfo.PROVIDER).getDirectParsedAssets();
    assertThat(directAssets.toList()).hasSize(1);

    ParsedAndroidAssets assets = directAssets.toList().get(0);
    assertThat(assets.getSymbols()).isNotNull();

    Artifact assetsTreeArtifact = Iterables.getOnlyElement(assets.getAssets());
    assertThat(assetsTreeArtifact.isTreeArtifact()).isTrue();
    assertThat(assetsTreeArtifact.getExecPathString()).endsWith("_aar/unzipped/assets/foo");
  }

  @Test
  public void testDatabindingInfoProvided() throws Exception {
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:last");

    DataBindingV2Provider provider = aarImportTarget.get(DataBindingV2Provider.PROVIDER);

    Artifact setterStore = provider.getSetterStores().toList().get(0);
    assertThat(setterStore.isTreeArtifact()).isTrue();
    assertThat(setterStore.getExecPathString())
        .endsWith("_aar/unzipped/data-binding-setter_store/last");

    assertThat(
            provider.getTransitiveBRFiles().toList().stream()
                .map(Artifact::getRootRelativePathString)
                .collect(toList()))
        .containsExactly(
            "a/_aar/unzipped/data-binding-br/baz",
            "a/_aar/unzipped/data-binding-br/foo",
            "a/_aar/unzipped/data-binding-br/bar",
            "a/_aar/unzipped/data-binding-br/intermediate",
            "a/_aar/unzipped/data-binding-br/last");
  }

  @Test
  public void testSourceJarsProvided() throws Exception {
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:foo");

    Iterable<Artifact> srcJars =
        JavaInfo.getProvider(JavaSourceJarsProvider.class, aarImportTarget).getSourceJars();
    assertThat(srcJars).hasSize(1);
    Artifact srcJar = Iterables.getOnlyElement(srcJars);
    assertThat(srcJar.getExecPathString()).endsWith("foo-src.jar");
  }

  @Test
  public void testSourceJarsCollectedTransitively() throws Exception {
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:bar");

    NestedSet<Artifact> srcJars =
        JavaInfo.getProvider(JavaSourceJarsProvider.class, aarImportTarget)
            .getTransitiveSourceJars();
    assertThat(ActionsTestUtil.baseArtifactNames(srcJars))
        .containsExactly("foo-src.jar", "bar-src.jar");
  }

  @Test
  public void testResourcesExtractor() throws Exception {
    ConfiguredTarget target = getConfiguredTarget("//a:foo");
    ValidatedAndroidResources resourceContainer =
        target.get(AndroidResourcesInfo.PROVIDER).getDirectAndroidResources().toList().get(0);

    Artifact resourceTreeArtifact = resourceContainer.getResources().get(0);
    Artifact aarResourcesExtractor =
        getDirectPrerequisite(
                target,
                ruleClassProvider.getToolsRepository() + "//tools/android:aar_resources_extractor")
            .getProvider(FilesToRunProvider.class)
            .getExecutable();

    ParsedAndroidAssets assets =
        target.get(AndroidAssetsInfo.PROVIDER).getDirectParsedAssets().toList().get(0);
    Artifact assetsTreeArtifact = assets.getAssets().get(0);

    DataBindingV2Provider dataBindingV2Provider = target.get(DataBindingV2Provider.PROVIDER);
    Artifact databindingBrTreeArtifact =
        dataBindingV2Provider.getTransitiveBRFiles().toList().get(0);
    Artifact databindingSetterStoreTreeArtifact =
        dataBindingV2Provider.getSetterStores().toList().get(0);

    assertThat(getGeneratingSpawnAction(resourceTreeArtifact).getArguments())
        .containsExactly(
            aarResourcesExtractor.getExecPathString(),
            "--input_aar",
            "a/foo.aar",
            "--output_res_dir",
            resourceTreeArtifact.getExecPathString(),
            "--output_assets_dir",
            assetsTreeArtifact.getExecPathString(),
            "--output_databinding_br_dir",
            databindingBrTreeArtifact.getExecPathString(),
            "--output_databinding_setter_store_dir",
            databindingSetterStoreTreeArtifact.getExecPathString());
  }

  @Test
  public void testDepsCheckerActionExistsForLevelError() throws Exception {
    useConfiguration("--experimental_import_deps_checking=ERROR");
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:last");
    OutputGroupInfo outputGroupInfo = aarImportTarget.get(OutputGroupInfo.STARLARK_CONSTRUCTOR);
    NestedSet<Artifact> outputGroup =
        outputGroupInfo.getOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL);
    assertThat(outputGroup.toList()).hasSize(2);

    // We should force asset merging to happen
    Artifact mergedAssetsZip =
        aarImportTarget.get(AndroidAssetsInfo.PROVIDER).getValidationResult();
    assertThat(outputGroup.toList()).contains(mergedAssetsZip);

    // Get the other artifact from the output group
    Artifact artifact = ActionsTestUtil.getFirstArtifactEndingWith(outputGroup, "jdeps.proto");

    assertThat(artifact.isTreeArtifact()).isFalse();
    assertThat(artifact.getExecPathString()).endsWith("_aar/last/jdeps.proto");

    SpawnAction checkerAction = getGeneratingSpawnAction(artifact);
    List<String> arguments = checkerAction.getArguments();
    assertThat(arguments)
        .containsAtLeast(
            "--bootclasspath_entry",
            "--classpath_entry",
            "--directdep",
            "--input",
            "--checking_mode=error",
            "--rule_label",
            "//a:last",
            "--jdeps_output");
    ensureArgumentsHaveClassEntryOptionWithSuffix(
        arguments, "/intermediate/classes_and_libs_merged.jar");
    assertThat(arguments.stream().filter(arg -> "--classpath_entry".equals(arg)).count())
        .isEqualTo(9); // transitive classpath
    assertThat(arguments.stream().filter(arg -> "--directdep".equals(arg)).count())
        .isEqualTo(2); // 1 declared dep
  }

  @Test
  public void testDepsCheckerActionExistsForLevelWarning() throws Exception {
    checkDepsCheckerActionExistsForLevel(ImportDepsCheckingLevel.WARNING, "warning");
  }

  @Test
  public void testDepsCheckerActionDoesNotExistsForLevelOff() throws Exception {
    useConfiguration("--experimental_import_deps_checking=off");
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:bar");
    OutputGroupInfo outputGroupInfo = aarImportTarget.get(OutputGroupInfo.STARLARK_CONSTRUCTOR);
    NestedSet<Artifact> outputGroup =
        outputGroupInfo.getOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL);
    assertThat(outputGroup.toList()).hasSize(1);
    assertThat(ActionsTestUtil.getFirstArtifactEndingWith(outputGroup, "jdeps.proto")).isNull();
  }

  private void checkDepsCheckerActionExistsForLevel(
      ImportDepsCheckingLevel level, String expectedCheckingMode) throws Exception {
    useConfiguration("--experimental_import_deps_checking=" + level.name());
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:bar");
    OutputGroupInfo outputGroupInfo = aarImportTarget.get(OutputGroupInfo.STARLARK_CONSTRUCTOR);
    NestedSet<Artifact> outputGroup =
        outputGroupInfo.getOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL);
    assertThat(outputGroup.toList()).hasSize(2);

    // We should force asset merging to happen
    Artifact mergedAssetsZip =
        aarImportTarget.get(AndroidAssetsInfo.PROVIDER).getValidationResult();
    assertThat(outputGroup.toList()).contains(mergedAssetsZip);

    // Get the other artifact from the output group
    Artifact artifact = ActionsTestUtil.getFirstArtifactEndingWith(outputGroup, "jdeps.proto");
    checkDepsCheckerOutputArtifact(artifact, expectedCheckingMode);
  }

  private void checkDepsCheckerOutputArtifact(Artifact artifact, String expectedCheckingMode)
      throws CommandLineExpansionException, InterruptedException {
    assertThat(artifact.isTreeArtifact()).isFalse();
    assertThat(artifact.getExecPathString()).endsWith("_aar/bar/jdeps.proto");

    SpawnAction checkerAction = getGeneratingSpawnAction(artifact);
    List<String> arguments = checkerAction.getArguments();
    assertThat(arguments)
        .containsAtLeast(
            "--bootclasspath_entry",
            "--classpath_entry",
            "--input",
            "--rule_label",
            "--jdeps_output",
            "--checking_mode=" + expectedCheckingMode);
  }

  /**
   * Tests whether the given argument list contains an argument nameds "--classpath_entry" with a
   * value that ends with the given suffix.
   */
  private static void ensureArgumentsHaveClassEntryOptionWithSuffix(
      List<String> arguments, String suffix) {
    assertThat(arguments).isNotEmpty();
    Iterator<String> iterator = arguments.iterator();
    assertThat(iterator.hasNext()).isTrue();
    String prev = iterator.next();
    while (iterator.hasNext()) {
      String current = iterator.next();
      if ("--classpath_entry".equals(prev) && current.endsWith(suffix)) {
        return; // Success.
      }
      prev = current;
    }
    Assert.fail(
        "The arguments does not have the expected --classpath_entry: The arguments are "
            + arguments
            + ", and the expected class entry suffix is "
            + suffix);
  }

  @Test
  public void testNativeLibsProvided() throws Exception {
    ConfiguredTarget androidLibraryTarget = getConfiguredTarget("//java:lib");

    NestedSet<Artifact> nativeLibs =
        androidLibraryTarget.get(AndroidNativeLibsInfo.PROVIDER).getNativeLibs();
    assertThat(nativeLibs.toList())
        .containsExactly(
            ActionsTestUtil.getFirstArtifactEndingWith(nativeLibs, "foo/native_libs.zip"),
            ActionsTestUtil.getFirstArtifactEndingWith(nativeLibs, "bar/native_libs.zip"),
            ActionsTestUtil.getFirstArtifactEndingWith(nativeLibs, "baz/native_libs.zip"));
  }

  @Test
  public void testNativeLibsMakesItIntoApk() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        """
        aar_import(
            name = "my_aar",
            aar = "my_aar.aar",
        )

        android_binary(
            name = "my_app",
            srcs = ["HelloApp.java"],
            manifest = "AndroidManifest.xml",
            deps = [":my_aar"],
        )
        """);
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:my_app");
    SpawnAction apkBuilderAction =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(binary), "my_app_unsigned.apk");
    assertThat(
            Iterables.find(
                apkBuilderAction.getArguments(),
                Predicates.containsPattern("_aar/my_aar/native_libs.zip$")))
        .isNotEmpty();
  }

  @Test
  public void testClassesJarProvided() throws Exception {
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:foo");

    Iterable<JavaOutput> javaOutputs =
        JavaInfo.getProvider(JavaRuleOutputJarsProvider.class, aarImportTarget).getJavaOutputs();
    assertThat(javaOutputs).hasSize(1);

    Artifact classesJar = javaOutputs.iterator().next().getClassJar();
    assertThat(classesJar.getFilename()).isEqualTo("classes_and_libs_merged.jar");

    SpawnAction jarMergingAction = ((SpawnAction) getGeneratingAction(classesJar));
    assertThat(jarMergingAction.getArguments()).contains("--dont_change_compression");
  }

  @Test
  public void testNoCustomJavaPackage() throws Exception {
    ValidatedAndroidResources resourceContainer =
        getConfiguredTarget("//a:foo")
            .get(AndroidResourcesInfo.PROVIDER)
            .getDirectAndroidResources()
            .toList()
            .get(0);

    // aar_import should not set a custom java package. Instead aapt will read the
    // java package from the manifest.
    assertThat(resourceContainer.getJavaPackage()).isNull();
  }

  @Test
  public void testDepsPropagatesMergedAarJars() throws Exception {
    Action appCompileAction =
        getGeneratingAction(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil()
                    .artifactClosureOf(getFileConfiguredTarget("//java:app.apk").getArtifact()),
                "libapp.jar"));
    assertThat(appCompileAction).isNotNull();
    assertThat(ActionsTestUtil.prettyArtifactNames(appCompileAction.getInputs()))
        .containsAtLeast(
            "a/_aar/foo/classes_and_libs_merged.jar",
            "a/_aar/bar/classes_and_libs_merged.jar",
            "a/_aar/baz/classes_and_libs_merged.jar");
  }

  @Test
  public void testExportsPropagatesMergedAarJars() throws Exception {
    FileConfiguredTarget appTarget = getFileConfiguredTarget("//java:app.apk");
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(appTarget.getArtifact());

    ConfiguredTarget bar = getConfiguredTarget("//a:bar");
    Artifact barClassesJar =
        ActionsTestUtil.getFirstArtifactEndingWith(artifacts, "bar/classes_and_libs_merged.jar");
    // Verify that bar/classes_and_libs_merged.jar was in the artifact closure.
    assertThat(barClassesJar).isNotNull();
    assertThat(barClassesJar.getArtifactOwner().getLabel()).isEqualTo(bar.getLabel());

    ConfiguredTarget foo = getConfiguredTarget("//a:foo");
    Artifact fooClassesJar =
        ActionsTestUtil.getFirstArtifactEndingWith(artifacts, "foo/classes_and_libs_merged.jar");
    // Verify that foo/classes_and_libs_merged.jar was in the artifact closure.
    assertThat(fooClassesJar).isNotNull();
    assertThat(fooClassesJar.getArtifactOwner().getLabel()).isEqualTo(foo.getLabel());

    ConfiguredTarget baz = getConfiguredTarget("//java:baz.jar");
    Artifact bazJar = ActionsTestUtil.getFirstArtifactEndingWith(artifacts, "baz.jar");
    // Verify that baz.jar was in the artifact closure
    assertThat(bazJar).isNotNull();
    assertThat(bazJar.getArtifactOwner().getLabel()).isEqualTo(baz.getLabel());
  }

  @Test
  public void testExportsPropagatesResources() throws Exception {
    FileConfiguredTarget appTarget = getFileConfiguredTarget("//java:app.apk");
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(appTarget.getArtifact());

    ConfiguredTarget bar = getConfiguredTarget("//a:bar");
    Artifact barResources =
        ActionsTestUtil.getFirstArtifactEndingWith(artifacts, "_aar/unzipped/resources/bar");
    assertThat(barResources).isNotNull();
    assertThat(barResources.getArtifactOwner().getLabel()).isEqualTo(bar.getLabel());

    ConfiguredTarget foo = getConfiguredTarget("//a:foo");
    Artifact fooResources =
        ActionsTestUtil.getFirstArtifactEndingWith(artifacts, "_aar/unzipped/resources/foo");
    assertThat(fooResources).isNotNull();
    assertThat(fooResources.getArtifactOwner().getLabel()).isEqualTo(foo.getLabel());
  }

  @Test
  public void testJavaCompilationArgsProvider() throws Exception {
    useConfiguration("--experimental_import_deps_checking=ERROR");
    ConfiguredTarget aarImportTarget = getConfiguredTarget("//a:bar");

    JavaCompilationArgsProvider provider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, aarImportTarget);
    assertThat(provider).isNotNull();
    assertThat(artifactsToStrings(provider.getRuntimeJars()))
        .containsExactly(
            "bin a/_aar/bar/classes_and_libs_merged.jar",
            "bin a/_aar/foo/classes_and_libs_merged.jar",
            "bin a/_aar/baz/classes_and_libs_merged.jar",
            "src java/baz.jar");
    List<Artifact> compileTimeJavaDependencyArtifacts =
        provider.getCompileTimeJavaDependencyArtifacts().toList();
    assertThat(compileTimeJavaDependencyArtifacts).hasSize(2);
    assertThat(
            compileTimeJavaDependencyArtifacts.stream()
                .filter(artifact -> artifact.getExecPathString().endsWith("/_aar/foo/jdeps.proto"))
                .collect(Collectors.toList()))
        .hasSize(1);
    assertThat(
            compileTimeJavaDependencyArtifacts.stream()
                .filter(artifact -> artifact.getExecPathString().endsWith("/_aar/bar/jdeps.proto"))
                .collect(Collectors.toList()))
        .hasSize(1);
  }

  @Test
  public void testExportsManifest() throws Exception {
    Artifact binaryMergedManifest =
        getConfiguredTarget("//java:app").get(ApkInfo.PROVIDER).getMergedManifest();
    // Compare root relative path strings instead of artifacts due to difference in configuration
    // caused by the Android split transition.
    assertThat(
            Iterables.transform(
                getGeneratingAction(binaryMergedManifest).getInputs().toList(),
                Artifact::getRootRelativePathString))
        .containsAtLeast(getAndroidManifest("//a:foo"), getAndroidManifest("//a:bar"));
  }

  private String getAndroidManifest(String aarImport) throws Exception {
    return getConfiguredTarget(aarImport)
        .get(AndroidResourcesInfo.PROVIDER)
        .getDirectAndroidResources()
        .toList()
        .get(0)
        .getManifest()
        .getRootRelativePathString();
  }

  @Test
  public void testRClassFromAarImportInCompileClasspath() throws Exception {
    Collection<Artifact> compilationClasspath =
        JavaInfo.getProvider(JavaCompilationInfoProvider.class, getConfiguredTarget("//a:library"))
            .getCompilationClasspath()
            .toList(Artifact.class);

    assertThat(
            compilationClasspath.stream()
                .filter(artifact -> artifact.getFilename().equalsIgnoreCase("foo_resources.jar"))
                .count())
        .isEqualTo(1);
  }
}
