// 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.AarImportTest.WithPlatforms;
import com.google.devtools.build.lib.rules.android.AarImportTest.WithoutPlatforms;
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;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

/** Tests for {@link com.google.devtools.build.lib.rules.android.AarImport}. */
@RunWith(Suite.class)
@SuiteClasses({WithoutPlatforms.class, WithPlatforms.class})
public abstract class AarImportTest extends AndroidBuildViewTestCase {
  /** Use legacy toolchain resolution. */
  @RunWith(JUnit4.class)
  public static class WithoutPlatforms extends AarImportTest {}

  /** Use platform-based toolchain resolution. */
  @RunWith(JUnit4.class)
  public static class WithPlatforms extends AarImportTest {
    @Override
    protected boolean platformBasedToolchains() {
      return true;
    }
  }

  @Before
  public void setup() throws Exception {
    scratch.file(
        "aapt2/sdk/BUILD",
        "android_sdk(",
        "    name = 'sdk',",
        "    aapt = 'aapt',",
        "    aapt2 = 'aapt2',",
        "    adb = 'adb',",
        "    aidl = 'aidl',",
        "    android_jar = 'android.jar',",
        "    apksigner = 'apksigner',",
        "    dx = 'dx',",
        "    framework_aidl = 'framework_aidl',",
        "    main_dex_classes = 'main_dex_classes',",
        "    main_dex_list_creator = 'main_dex_list_creator',",
        "    proguard = 'proguard',",
        "    shrinked_android_jar = 'shrinked_android_jar',",
        "    zipalign = 'zipalign',",
        "    tags = ['__ANDROID_RULES_MIGRATION__'],",
        ")");
    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',",
        "    deps = [':baz'],",
        "    exports = [':foo', '//java:baz'],",
        ")",
        "aar_import(",
        "    name = 'intermediate',",
        "    aar = 'intermediate.aar',",
        "    deps = [':bar']",
        ")",
        "aar_import(",
        "    name = 'last',",
        "    aar = 'last.aar',",
        "    deps = [':intermediate'],",
        ")",
        "android_library(",
        "    name = 'library',",
        "    manifest = 'AndroidManifest.xml',",
        "    custom_package = 'com.google.arrimport',",
        "    resource_files = ['res/values/values.xml'],",
        "    srcs = ['App.java'],",
        "    deps = [':foo'],",
        ")");
    scratch.file(
        "java/BUILD",
        "android_binary(",
        "    name = 'app',",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['App.java'],",
        "    deps = ['//a:bar'],",
        ")",
        "android_library(",
        "    name = 'lib',",
        "    exports = ['//a:bar'],",
        ")",
        "java_import(",
        "    name = 'baz',",
        "    jars = ['baz.jar'],",
        "    constraints = ['android'],",
        ")");
    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 {
    useConfiguration("--android_sdk=//aapt2/sdk:sdk");

    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'],",
        "    deps = [':my_aar'],",
        "    manifest = 'AndroidManifest.xml',",
        ")");
    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 testFailsWithoutAndroidSdk() throws Exception {
    scratch.file("sdk/BUILD", "alias(", "    name = 'sdk',", "    actual = 'doesnotexist',", ")");
    useConfiguration("--android_sdk=//sdk");
    checkError(
        "aar",
        "aar",
        platformBasedToolchains()
            ? "resolved to target //sdk:sdk, but that target does not provide ToolchainInfo"
            : "No Android SDK found. Use the --android_sdk command line option to specify one.",
        "aar_import(",
        "    name = 'aar',",
        "    aar = 'a.aar',",
        ")");
  }

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