// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.rules.android;

import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.devtools.build.lib.syntax.Type.STRING;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidManifestMerger;
import com.google.devtools.build.lib.rules.android.ResourceContainer.Builder.JavaPackageSource;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import javax.annotation.Nullable;

/** Represents a AndroidManifest, that may have been merged from dependencies. */
public final class ApplicationManifest {

  public ApplicationManifest createSplitManifest(
      RuleContext ruleContext, String splitName, boolean hasCode) {
    Artifact result = createSplitManifest(ruleContext, manifest, splitName, hasCode);
    return new ApplicationManifest(ruleContext, result, targetAaptVersion);
  }

  static Artifact createSplitManifest(
      RuleContext ruleContext, Artifact manifest, String splitName, boolean hasCode) {
    // aapt insists that manifests be called AndroidManifest.xml, even though they have to be
    // explicitly designated as manifests on the command line
    Artifact result =
        AndroidBinary.getDxArtifact(ruleContext, "split_" + splitName + "/AndroidManifest.xml");
    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(
                ruleContext.getExecutablePrerequisite("$build_split_manifest", Mode.HOST))
            .setProgressMessage("Creating manifest for split %s", splitName)
            .setMnemonic("AndroidBuildSplitManifest")
            .addInput(manifest)
            .addOutput(result);
    CustomCommandLine.Builder commandLine =
        CustomCommandLine.builder()
            .addExecPath("--main_manifest", manifest)
            .addExecPath("--split_manifest", result)
            .add("--split", splitName);
    if (hasCode) {
      commandLine.add("--hascode");
    } else {
      commandLine.add("--nohascode");
    }

    String overridePackage = getManifestValues(ruleContext).get("applicationId");
    if (overridePackage != null) {
      commandLine.add("--override_package", overridePackage);
    }

    builder.addCommandLine(commandLine.build());
    ruleContext.registerAction(builder.build(ruleContext));
    return result;
  }

  public ApplicationManifest addMobileInstallStubApplication(RuleContext ruleContext)
      throws InterruptedException {
    Artifact stubManifest = addMobileInstallStubApplication(ruleContext, manifest);
    return new ApplicationManifest(ruleContext, stubManifest, targetAaptVersion);
  }

  static Artifact addMobileInstallStubApplication(RuleContext ruleContext, Artifact manifest)
      throws InterruptedException {

    Artifact stubManifest =
        ruleContext.getImplicitOutputArtifact(
            AndroidRuleClasses.MOBILE_INSTALL_STUB_APPLICATION_MANIFEST);
    Artifact stubData =
        ruleContext.getImplicitOutputArtifact(
            AndroidRuleClasses.MOBILE_INSTALL_STUB_APPLICATION_DATA);

    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(ruleContext.getExecutablePrerequisite("$stubify_manifest", Mode.HOST))
            .setProgressMessage("Injecting mobile install stub application")
            .setMnemonic("InjectMobileInstallStubApplication")
            .addInput(manifest)
            .addOutput(stubManifest)
            .addOutput(stubData);
    CustomCommandLine.Builder commandLine =
        CustomCommandLine.builder()
            .add("--mode=mobile_install")
            .addExecPath("--input_manifest", manifest)
            .addExecPath("--output_manifest", stubManifest)
            .addExecPath("--output_datafile", stubData);

    String overridePackage = getManifestValues(ruleContext).get("applicationId");
    if (overridePackage != null) {
      commandLine.add("--override_package", overridePackage);
    }

    builder.addCommandLine(commandLine.build());
    ruleContext.registerAction(builder.build(ruleContext));

    return stubManifest;
  }

  public static Artifact getManifestFromAttributes(RuleContext ruleContext) {
    return ruleContext.getPrerequisiteArtifact("manifest", Mode.TARGET);
  }

  /**
   * Gets the manifest specified in the "manifest" attribute, renaming it if needed.
   *
   * <p>Unlike {@link AndroidSemantics#getManifestForRule(RuleContext)}, this method will not
   * perform AndroidSemantics-specific manifest processing. This method will do the same work
   * regardless of the AndroidSemantics implementation being used; that method may do different work
   * depending on the implementation.
   */
  public static ApplicationManifest renamedFromRule(RuleContext ruleContext)
      throws InterruptedException, RuleErrorException {
    return fromExplicitManifest(
        ruleContext, renameManifestIfNeeded(ruleContext, getManifestFromAttributes(ruleContext)));
  }

  static Artifact renameManifestIfNeeded(RuleContext ruleContext, Artifact manifest)
      throws InterruptedException {
    if (manifest.getFilename().equals("AndroidManifest.xml")) {
      return manifest;
    } else {
      /*
       * If the manifest file is not named AndroidManifest.xml, we create a symlink named
       * AndroidManifest.xml to it. aapt requires the manifest to be named as such.
       */
      Artifact manifestSymlink =
          ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_SYMLINKED_MANIFEST);
      SymlinkAction symlinkAction =
          new SymlinkAction(
              ruleContext.getActionOwner(),
              manifest,
              manifestSymlink,
              "Renaming Android manifest for " + ruleContext.getLabel());
      ruleContext.registerAction(symlinkAction);
      return manifestSymlink;
    }
  }

  public static ApplicationManifest fromExplicitManifest(RuleContext ruleContext, Artifact manifest)
      throws RuleErrorException {
    return new ApplicationManifest(
        ruleContext, manifest, AndroidAaptVersion.chooseTargetAaptVersion(ruleContext));
  }

  /**
   * Generates an empty manifest for a rule that does not directly specify resources.
   *
   * <p><strong>Note:</strong> This generated manifest can then be used as the primary manifest when
   * merging with dependencies.
   *
   * @return the generated ApplicationManifest
   */
  public static ApplicationManifest generatedManifest(RuleContext ruleContext)
      throws RuleErrorException {
    return fromExplicitManifest(
        ruleContext, generateManifest(ruleContext, AndroidCommon.getJavaPackage(ruleContext)));
  }

  /**
   * Creates an action to generate an empty manifest file with a specific package name.
   *
   * @return an artifact for the generated manifest
   */
  public static Artifact generateManifest(RuleContext ruleContext, String manifestPackage) {
    Artifact generatedManifest =
        ruleContext.getUniqueDirectoryArtifact(
            ruleContext.getRule().getName() + "_generated",
            PathFragment.create("AndroidManifest.xml"),
            ruleContext.getBinOrGenfilesDirectory());

    String contents =
        Joiner.on("\n")
            .join(
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>",
                "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"",
                "          package=\"" + manifestPackage + "\">",
                "   <application>",
                "   </application>",
                "</manifest>");
    ruleContext
        .getAnalysisEnvironment()
        .registerAction(
            FileWriteAction.create(
                ruleContext, generatedManifest, contents, /*makeExecutable=*/ false));
    return generatedManifest;
  }

  /** Gets a map of manifest values from this rule's 'manifest_values' attribute */
  static ImmutableMap<String, String> getManifestValues(RuleContext context) {
    return getManifestValues(
        context,
        context.attributes().isAttributeValueExplicitlySpecified("manifest_values")
            ? context.attributes().get("manifest_values", Type.STRING_DICT)
            : null);
  }

  /** Gets and expands an expanded map of manifest values from some raw map of manifest values. */
  static ImmutableMap<String, String> getManifestValues(
      RuleContext ruleContext, @Nullable Map<String, String> rawMap) {
    Map<String, String> manifestValues = new TreeMap<>();
    if (rawMap != null) {
      manifestValues.putAll(rawMap);
    }

    for (String variable : manifestValues.keySet()) {
      manifestValues.put(
          variable,
          ruleContext.getExpander().expand("manifest_values", manifestValues.get(variable)));
    }
    return ImmutableMap.copyOf(manifestValues);
  }

  public ImmutableMap<String, String> getManifestValues() {
    return manifestValues;
  }

  private final Artifact manifest;
  private final ImmutableMap<String, String> manifestValues;
  private final AndroidAaptVersion targetAaptVersion;

  private ApplicationManifest(
      RuleContext ruleContext, Artifact manifest, AndroidAaptVersion targetAaptVersion) {
    this.manifest = manifest;
    this.manifestValues = getManifestValues(ruleContext);
    this.targetAaptVersion = targetAaptVersion;
  }

  public ApplicationManifest mergeWith(RuleContext ruleContext, ResourceDependencies resourceDeps) {
    return maybeMergeWith(
            ruleContext,
            manifest,
            resourceDeps,
            manifestValues,
            useLegacyMerging(ruleContext),
            AndroidCommon.getJavaPackage(ruleContext))
        .map(merged -> new ApplicationManifest(ruleContext, merged, targetAaptVersion))
        .orElse(this);
  }

  static Optional<Artifact> maybeMergeWith(
      RuleContext ruleContext,
      Artifact primaryManifest,
      ResourceDependencies resourceDeps,
      Map<String, String> manifestValues,
      boolean useLegacyMerging,
      String customPackage) {
    Map<Artifact, Label> mergeeManifests = getMergeeManifests(resourceDeps.getResourceContainers());

    if (useLegacyMerging) {
      if (!mergeeManifests.isEmpty()) {

        Artifact outputManifest =
            ruleContext.getUniqueDirectoryArtifact(
                ruleContext.getRule().getName() + "_merged",
                "AndroidManifest.xml",
                ruleContext.getBinOrGenfilesDirectory());
        AndroidManifestMergeHelper.createMergeManifestAction(
            ruleContext,
            primaryManifest,
            mergeeManifests.keySet(),
            ImmutableList.of("all"),
            outputManifest);
        return Optional.of(outputManifest);
      }
    } else {
      if (!mergeeManifests.isEmpty() || !manifestValues.isEmpty()) {
        Artifact outputManifest =
            ruleContext.getUniqueDirectoryArtifact(
                ruleContext.getRule().getName() + "_merged",
                "AndroidManifest.xml",
                ruleContext.getBinOrGenfilesDirectory());
        Artifact mergeLog =
            ruleContext.getUniqueDirectoryArtifact(
                ruleContext.getRule().getName() + "_merged",
                "manifest_merger_log.txt",
                ruleContext.getBinOrGenfilesDirectory());
        new ManifestMergerActionBuilder(ruleContext)
            .setManifest(primaryManifest)
            .setMergeeManifests(mergeeManifests)
            .setLibrary(false)
            .setManifestValues(manifestValues)
            .setCustomPackage(customPackage)
            .setManifestOutput(outputManifest)
            .setLogOut(mergeLog)
            .build(ruleContext);
        return Optional.of(outputManifest);
      }
    }
    return Optional.empty();
  }

  /** Checks if the legacy manifest merger should be used, based on a rule attribute */
  static boolean useLegacyMerging(RuleContext ruleContext) {
    return ruleContext.isLegalFragment(AndroidConfiguration.class)
        && ruleContext.getRule().isAttrDefined("manifest_merger", STRING)
        && useLegacyMerging(ruleContext, ruleContext.attributes().get("manifest_merger", STRING));
  }

  /**
   * Checks if the legacy manifest merger should be used, based on an optional string specifying the
   * merger to use.
   */
  public static boolean useLegacyMerging(RuleContext ruleContext, @Nullable String mergerString) {
    AndroidManifestMerger merger = AndroidManifestMerger.fromString(mergerString);
    if (merger == null) {
      merger = ruleContext.getFragment(AndroidConfiguration.class).getManifestMerger();
    }
    if (merger == AndroidManifestMerger.LEGACY) {
      ruleContext.ruleWarning(
          "manifest_merger 'legacy' is deprecated. Please update to 'android'.\n"
              + "See https://developer.android.com/studio/build/manifest-merge.html for more "
              + "information about the manifest merger.");
    }

    return merger == AndroidManifestMerger.LEGACY;
  }

  private static Map<Artifact, Label> getMergeeManifests(
      Iterable<ValidatedAndroidData> transitiveData) {
    ImmutableSortedMap.Builder<Artifact, Label> builder =
        ImmutableSortedMap.orderedBy(Artifact.EXEC_PATH_COMPARATOR);
    for (ValidatedAndroidData d : transitiveData) {
      if (d.isManifestExported()) {
        builder.put(d.getManifest(), d.getLabel());
      }
    }
    return builder.build();
  }

  public ApplicationManifest renamePackage(RuleContext ruleContext, String customPackage) {
    Optional<Artifact> stamped = maybeSetManifestPackage(ruleContext, manifest, customPackage);

    if (!stamped.isPresent()) {
      return this;
    }

    return new ApplicationManifest(ruleContext, stamped.get(), targetAaptVersion);
  }

  static Optional<Artifact> maybeSetManifestPackage(
      RuleContext ruleContext, Artifact manifest, String customPackage) {
    if (isNullOrEmpty(customPackage)) {
      return Optional.empty();
    }
    Artifact outputManifest =
        ruleContext.getUniqueDirectoryArtifact(
            ruleContext.getRule().getName() + "_renamed",
            "AndroidManifest.xml",
            ruleContext.getBinOrGenfilesDirectory());
    new ManifestMergerActionBuilder(ruleContext)
        .setManifest(manifest)
        .setLibrary(true)
        .setCustomPackage(customPackage)
        .setManifestOutput(outputManifest)
        .build(ruleContext);

    return Optional.of(outputManifest);
  }

  public ResourceApk packTestWithDataAndResources(
      RuleContext ruleContext,
      Artifact resourceApk,
      ResourceDependencies resourceDeps,
      @Nullable Artifact rTxt,
      boolean incremental,
      Artifact proguardCfg,
      Artifact mainDexProguardCfg,
      @Nullable String packageUnderTest,
      boolean hasLocalResourceFiles)
      throws InterruptedException, RuleErrorException {

    ResourceContainer resourceContainer =
        ResourceContainer.builderFromRule(ruleContext)
            .setAndroidAssets(AndroidAssets.from(ruleContext))
            .setAndroidResources(AndroidResources.from(ruleContext, "local_resource_files"))
            .setManifest(getManifest())
            .setApk(resourceApk)
            .setRTxt(rTxt)
            .build();

    AndroidResourcesProcessorBuilder builder =
        new AndroidResourcesProcessorBuilder(ruleContext)
            .setLibrary(false)
            .setApkOut(resourceContainer.getApk())
            .setUncompressedExtensions(ImmutableList.of())
            .setCrunchPng(true)
            .setJavaPackage(resourceContainer.getJavaPackage())
            .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
            .withResourceDependencies(resourceDeps)
            .setProguardOut(proguardCfg)
            .setMainDexProguardOut(mainDexProguardCfg)
            .setApplicationId(manifestValues.get("applicationId"))
            .setVersionCode(manifestValues.get("versionCode"))
            .setVersionName(manifestValues.get("versionName"))
            .setThrowOnResourceConflict(
                ruleContext
                    .getConfiguration()
                    .getFragment(AndroidConfiguration.class)
                    .throwOnResourceConflict())
            .setPackageUnderTest(packageUnderTest)
            .setIsTestWithResources(hasLocalResourceFiles);
    if (!incremental) {
      builder
          .targetAaptVersion(targetAaptVersion)
          .setRTxtOut(resourceContainer.getRTxt())
          .setSymbols(resourceContainer.getSymbols())
          .setSourceJarOut(resourceContainer.getJavaSourceJar());
    }
    ResourceContainer processed = builder.build(resourceContainer);

    ResourceContainer finalContainer =
        new RClassGeneratorActionBuilder(ruleContext)
            .targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
            .withDependencies(resourceDeps)
            .setClassJarOut(
                ruleContext.getImplicitOutputArtifact(
                    AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
            .build(processed);

    return ResourceApk.of(finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg);
  }

  /** Packages up the manifest with resource and assets from the LocalResourceContainer. */
  public ResourceApk packAarWithDataAndResources(
      RuleContext ruleContext,
      AndroidAssets assets,
      AndroidResources resources,
      ResourceDependencies resourceDeps,
      Artifact rTxt,
      Artifact symbols,
      Artifact manifestOut,
      Artifact mergedResources)
      throws InterruptedException {
    ResourceContainer resourceContainer =
        ResourceContainer.builderFromRule(ruleContext)
            .setRTxt(rTxt)
            .setJavaPackageFrom(JavaPackageSource.MANIFEST)
            .setManifestExported(true)
            .setManifest(getManifest())
            .build();

    // android_library should only build the APK one way (!incremental).
    Artifact rJavaClassJar =
        ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR);

    resourceContainer =
        new AndroidResourceParsingActionBuilder(ruleContext)
            .setAssets(assets)
            .setResources(resources)
            .setOutput(symbols)
            .buildAndUpdate(ruleContext, resourceContainer);

    ResourceContainer merged =
        new AndroidResourceMergingActionBuilder(ruleContext)
            .setJavaPackage(resourceContainer.getJavaPackage())
            .withDependencies(resourceDeps)
            .setMergedResourcesOut(mergedResources)
            .setManifestOut(manifestOut)
            .setClassJarOut(rJavaClassJar)
            .setThrowOnResourceConflict(
                ruleContext
                    .getConfiguration()
                    .getFragment(AndroidConfiguration.class)
                    .throwOnResourceConflict())
            .build(ruleContext, resourceContainer);

    ResourceContainer processed =
        new AndroidResourceValidatorActionBuilder(ruleContext)
            .setJavaPackage(merged.getJavaPackage())
            .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
            .setMergedResources(mergedResources)
            .setRTxtOut(merged.getRTxt())
            .setSourceJarOut(merged.getJavaSourceJar())
            .setApkOut(resourceContainer.getApk())
            // aapt2 related artifacts. Will be generated if the targetAaptVersion is AAPT2.
            .withDependencies(resourceDeps)
            .setCompiledSymbols(merged.getCompiledSymbols())
            .setAapt2RTxtOut(merged.getAapt2RTxt())
            .setAapt2SourceJarOut(merged.getAapt2JavaSourceJar())
            .setStaticLibraryOut(merged.getStaticLibrary())
            .build(ruleContext, merged);

    return ResourceApk.of(processed, resourceDeps);
  }

  /* Creates an incremental apk from assets and data. */
  public ResourceApk packIncrementalBinaryWithDataAndResources(
      RuleContext ruleContext,
      Artifact resourceApk,
      ResourceDependencies resourceDeps,
      List<String> uncompressedExtensions,
      boolean crunchPng,
      Artifact proguardCfg)
      throws InterruptedException, RuleErrorException {
    AndroidResources resources = AndroidResources.from(ruleContext, "resource_files");

    // Filter the resources during analysis to prevent processing of dependencies on unwanted
    // resources during execution.
    ResourceFilterFactory resourceFilterFactory =
        ResourceFilterFactory.fromRuleContext(ruleContext);
    ResourceFilter resourceFilter =
        resourceFilterFactory.getResourceFilter(ruleContext, resourceDeps, resources);
    resources = resources.filterLocalResources(ruleContext, resourceFilter);
    resourceDeps = resourceDeps.filter(ruleContext, resourceFilter);

    // Now that the LocalResourceContainer has been filtered, we can build a filtered resource
    // container from it.
    ResourceContainer resourceContainer =
        ResourceContainer.builderFromRule(ruleContext)
            .setApk(resourceApk)
            .setManifest(getManifest())
            .setAndroidAssets(AndroidAssets.from(ruleContext))
            .setAndroidResources(resources)
            .build();

    ResourceContainer processed =
        new AndroidResourcesProcessorBuilder(ruleContext)
            .setLibrary(false)
            .setApkOut(resourceContainer.getApk())
            .setResourceFilterFactory(resourceFilterFactory)
            .setUncompressedExtensions(uncompressedExtensions)
            .setCrunchPng(crunchPng)
            .setJavaPackage(resourceContainer.getJavaPackage())
            .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
            .withResourceDependencies(resourceDeps)
            .setProguardOut(proguardCfg)
            .setApplicationId(manifestValues.get("applicationId"))
            .setVersionCode(manifestValues.get("versionCode"))
            .setVersionName(manifestValues.get("versionName"))
            .setThrowOnResourceConflict(
                ruleContext
                    .getConfiguration()
                    .getFragment(AndroidConfiguration.class)
                    .throwOnResourceConflict())
            .setPackageUnderTest(null)
            .build(resourceContainer);

    // Intentionally skip building an R class JAR - incremental binaries handle this separately.

    return ResourceApk.of(processed, resourceDeps, proguardCfg, null);
  }

  /** Packages up the manifest with resource and assets from the rule and dependent resources. */
  // TODO(bazel-team): this method calls for some refactoring, 15+ params including some nullables.
  public ResourceApk packBinaryWithDataAndResources(
      RuleContext ruleContext,
      Artifact resourceApk,
      ResourceDependencies resourceDeps,
      @Nullable Artifact rTxt,
      ResourceFilterFactory resourceFilterFactory,
      List<String> uncompressedExtensions,
      boolean crunchPng,
      Artifact proguardCfg,
      @Nullable Artifact mainDexProguardCfg,
      boolean conditionalKeepRules,
      Artifact manifestOut,
      Artifact mergedResources,
      @Nullable Artifact dataBindingInfoZip,
      @Nullable Artifact featureOf,
      @Nullable Artifact featureAfter)
      throws InterruptedException, RuleErrorException {

    AndroidResources resources = AndroidResources.from(ruleContext, "resource_files");
    ResourceFilter resourceFilter =
        resourceFilterFactory.getResourceFilter(ruleContext, resourceDeps, resources);
    resources = resources.filterLocalResources(ruleContext, resourceFilter);
    resourceDeps = resourceDeps.filter(ruleContext, resourceFilter);

    // Now that the LocalResourceContainer has been filtered, we can build a filtered resource
    // container from it.
    ResourceContainer resourceContainer =
        ResourceContainer.builderFromRule(ruleContext)
            .setAndroidAssets(AndroidAssets.from(ruleContext))
            .setAndroidResources(resources)
            .setManifest(getManifest())
            .setRTxt(rTxt)
            .setApk(resourceApk)
            .build();

    AndroidConfiguration androidConfiguration =
        ruleContext.getConfiguration().getFragment(AndroidConfiguration.class);

    boolean skipParsingAction =
        targetAaptVersion == AndroidAaptVersion.AAPT2 && androidConfiguration.skipParsingAction();

    if (conditionalKeepRules && targetAaptVersion != AndroidAaptVersion.AAPT2) {
      throw ruleContext.throwWithRuleError(
          "resource cycle shrinking can only be enabled for builds with aapt2");
    }

    ResourceContainer processed =
        new AndroidResourcesProcessorBuilder(ruleContext)
            .setLibrary(false)
            .setApkOut(resourceContainer.getApk())
            .setResourceFilterFactory(resourceFilterFactory)
            .setUncompressedExtensions(uncompressedExtensions)
            .setCrunchPng(crunchPng)
            .setJavaPackage(resourceContainer.getJavaPackage())
            .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
            .setManifestOut(manifestOut)
            .setMergedResourcesOut(mergedResources)
            .withResourceDependencies(resourceDeps)
            .setProguardOut(proguardCfg)
            .setMainDexProguardOut(mainDexProguardCfg)
            .conditionalKeepRules(conditionalKeepRules)
            .setDataBindingInfoZip(dataBindingInfoZip)
            .setApplicationId(manifestValues.get("applicationId"))
            .setVersionCode(manifestValues.get("versionCode"))
            .setVersionName(manifestValues.get("versionName"))
            .setFeatureOf(featureOf)
            .setFeatureAfter(featureAfter)
            .setThrowOnResourceConflict(androidConfiguration.throwOnResourceConflict())
            .setUseCompiledResourcesForMerge(skipParsingAction)
            .targetAaptVersion(targetAaptVersion)
            .setRTxtOut(resourceContainer.getRTxt())
            .setSymbols(resourceContainer.getSymbols())
            .setSourceJarOut(resourceContainer.getJavaSourceJar())
            .build(resourceContainer);

    ResourceContainer finalContainer =
        new RClassGeneratorActionBuilder(ruleContext)
            .targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
            .withDependencies(resourceDeps)
            .setClassJarOut(
                ruleContext.getImplicitOutputArtifact(
                    AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
            .build(processed);

    return ResourceApk.of(finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg);
  }

  public ResourceApk packLibraryWithDataAndResources(
      RuleContext ruleContext,
      ResourceDependencies resourceDeps,
      Artifact rTxt,
      Artifact symbols,
      Artifact manifestOut,
      Artifact mergedResources,
      @Nullable Artifact dataBindingInfoZip)
      throws InterruptedException, RuleErrorException {
    AndroidResources resources = AndroidResources.from(ruleContext, "resource_files");
    AndroidAssets assets = AndroidAssets.from(ruleContext);

    ResourceContainer.Builder builder =
        ResourceContainer.builderFromRule(ruleContext)
            .setManifest(getManifest())
            .setSymbols(symbols)
            .setRTxt(rTxt)
            // Request an APK so it can be inherited when a library is used in a binary's
            // resources attr.
            // TODO(b/30307842): Remove this once it is no longer needed for resources migration.
            .setApk(ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_LIBRARY_APK));

    if (targetAaptVersion == AndroidAaptVersion.AAPT2) {
      builder
          .setAapt2JavaSourceJar(
              ruleContext.getImplicitOutputArtifact(
                  AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_SOURCE_JAR))
          .setAapt2RTxt(
              ruleContext.getImplicitOutputArtifact(
                  AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_R_TXT))
          .setCompiledSymbols(
              ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_COMPILED_SYMBOLS))
          .setStaticLibrary(
              ruleContext.getImplicitOutputArtifact(
                  AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_LIBRARY_APK));
    }

    ResourceContainer resourceContainer = builder.build();

    Artifact rJavaClassJar =
        ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR);

    AndroidConfiguration androidConfiguration =
        ruleContext.getConfiguration().getFragment(AndroidConfiguration.class);

    boolean skipParsingAction =
        targetAaptVersion == AndroidAaptVersion.AAPT2 && androidConfiguration.skipParsingAction();

    AndroidResourceParsingActionBuilder parsingBuilder =
        new AndroidResourceParsingActionBuilder(ruleContext)
            .setAssets(assets)
            .setResources(resources)
            .setOutput(resourceContainer.getSymbols())
            .setCompiledSymbolsOutput(resourceContainer.getCompiledSymbols());

    if (dataBindingInfoZip != null && resourceContainer.getCompiledSymbols() != null) {
      PathFragment unusedInfo = dataBindingInfoZip.getRootRelativePath();
      // TODO(corysmith): Centralize the data binding processing and zipping into a single
      // action. Data binding processing needs to be triggered here as well as the merger to
      // avoid aapt2 from throwing an error during compilation.
      parsingBuilder
          .setDataBindingInfoZip(
              ruleContext.getDerivedArtifact(
                  unusedInfo.replaceName(unusedInfo.getBaseName() + "_unused.zip"),
                  dataBindingInfoZip.getRoot()))
          .setManifest(resourceContainer.getManifest())
          .setJavaPackage(resourceContainer.getJavaPackage());
    }
    resourceContainer = parsingBuilder.buildAndUpdate(ruleContext, resourceContainer);

    ResourceContainer merged =
        new AndroidResourceMergingActionBuilder(ruleContext)
            .setJavaPackage(resourceContainer.getJavaPackage())
            .withDependencies(resourceDeps)
            .setThrowOnResourceConflict(androidConfiguration.throwOnResourceConflict())
            .setUseCompiledMerge(skipParsingAction)
            .setDataBindingInfoZip(dataBindingInfoZip)
            .setMergedResourcesOut(mergedResources)
            .setManifestOut(manifestOut)
            .setClassJarOut(rJavaClassJar)
            .setDataBindingInfoZip(dataBindingInfoZip)
            .build(ruleContext, resourceContainer);

    ResourceContainer processed =
        new AndroidResourceValidatorActionBuilder(ruleContext)
            .setJavaPackage(merged.getJavaPackage())
            .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
            .setMergedResources(mergedResources)
            .setRTxtOut(merged.getRTxt())
            .setSourceJarOut(merged.getJavaSourceJar())
            .setApkOut(resourceContainer.getApk())
            // aapt2 related artifacts. Will be generated if the targetAaptVersion is AAPT2.
            .withDependencies(resourceDeps)
            .setCompiledSymbols(merged.getCompiledSymbols())
            .setAapt2RTxtOut(merged.getAapt2RTxt())
            .setAapt2SourceJarOut(merged.getAapt2JavaSourceJar())
            .setStaticLibraryOut(merged.getStaticLibrary())
            .build(ruleContext, merged);

    return ResourceApk.of(processed, resourceDeps);
  }

  public Artifact getManifest() {
    return manifest;
  }
}
