// Copyright 2018 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.devtools.build.lib.analysis.config.CompilationMode.OPT;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.analysis.Allowlist;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RuleErrorConsumer;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.starlarkbuildapi.android.AndroidDataContextApi;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;

/**
 * Wraps common tools and settings used for working with Android assets, resources, and manifests.
 *
 * <p>Do not create implementation classes directly - instead, get the appropriate one from {@link
 * com.google.devtools.build.lib.rules.android.AndroidSemantics}.
 *
 * <p>The {@link Label}, {@link ActionConstructionContext}, and BusyBox {@link FilesToRunProvider}
 * are needed to create virtually all actions for working with Android data, so it makes sense to
 * bundle them together. Additionally, this class includes some common tools (such as an SDK) that
 * are used in BusyBox actions.
 */
public class AndroidDataContext implements AndroidDataContextApi {

  // Feature which would cause AndroidCompiledResourceMerger actions to pass a flag with the same
  // name to ResourceProcessorBusyBox.
  private static final String ANNOTATE_R_FIELDS_FROM_TRANSITIVE_DEPS =
      "annotate_r_fields_from_transitive_deps";

  // If specified, omit resources from transitive dependencies when generating Android R classes.
  private static final String OMIT_TRANSITIVE_RESOURCES_FROM_ANDROID_R_CLASSES =
      "android_resources_strict_deps";

  // Feature which would enable AAPT2's resource name obfuscation optimization for android_binary
  // rules with resource shrinking and ProGuard/AppReduce enabled.
  private static final String FEATURE_RESOURCE_NAME_OBFUSCATION = "resource_name_obfuscation";

  private final RuleContext ruleContext;
  private final FilesToRunProvider busybox;
  private final AndroidSdkProvider sdk;
  private final boolean persistentBusyboxToolsEnabled;
  private final boolean optOutOfResourcePathShortening;
  private final boolean optOutOfResourceNameObfuscation;
  private final boolean throwOnShrinkResources;
  private final boolean throwOnProguardApplyDictionary;
  private final boolean throwOnProguardApplyMapping;
  private final boolean throwOnResourceConflict;
  private final boolean useDataBindingV2;
  private final boolean useDataBindingAndroidX;
  private final boolean includeProguardLocationReferences;
  private final ImmutableMap<String, String> executionInfo;

  public static AndroidDataContext forNative(RuleContext ruleContext) {
    return makeContext(ruleContext);
  }

  public static AndroidDataContext makeContext(RuleContext ruleContext) {
    AndroidConfiguration androidConfig =
        ruleContext.getConfiguration().getFragment(AndroidConfiguration.class);

    ImmutableMap<String, String> executionInfo =
        TargetUtils.getExecutionInfo(ruleContext.getRule(), ruleContext.isAllowTagsPropagation());

    return new AndroidDataContext(
        ruleContext,
        ruleContext.getExecutablePrerequisite("$android_resources_busybox"),
        androidConfig.persistentBusyboxTools(),
        AndroidSdkProvider.fromRuleContext(ruleContext),
        hasExemption(ruleContext, "allow_raw_access_to_resource_paths", false),
        hasExemption(ruleContext, "allow_resource_name_obfuscation_opt_out", false),
        !hasExemption(ruleContext, "allow_shrink_resources_attribute", true),
        !hasExemption(ruleContext, "allow_proguard_apply_dictionary", true),
        !hasExemption(ruleContext, "allow_proguard_apply_mapping", true),
        !hasExemption(ruleContext, "allow_resource_conflicts", true),
        androidConfig.useDataBindingV2(),
        androidConfig.useDataBindingAndroidX(),
        androidConfig.includeProguardLocationReferences(),
        executionInfo);
  }

  private static boolean hasExemption(
      RuleContext ruleContext, String exemptionName, boolean valueIfNoAllowlist) {
    return Allowlist.hasAllowlist(ruleContext, exemptionName)
        ? Allowlist.isAvailable(ruleContext, exemptionName)
        : valueIfNoAllowlist;
  }

  protected AndroidDataContext(
      RuleContext ruleContext,
      FilesToRunProvider busybox,
      boolean persistentBusyboxToolsEnabled,
      AndroidSdkProvider sdk,
      boolean optOutOfResourcePathShortening,
      boolean optOutOfResourceNameObfuscation,
      boolean throwOnShrinkResources,
      boolean throwOnProguardApplyDictionary,
      boolean throwOnProguardApplyMapping,
      boolean throwOnResourceConflict,
      boolean useDataBindingV2,
      boolean useDataBindingAndroidX,
      boolean includeProguardLocationReferences,
      ImmutableMap<String, String> executionInfo) {
    this.persistentBusyboxToolsEnabled = persistentBusyboxToolsEnabled;
    this.ruleContext = ruleContext;
    this.busybox = busybox;
    this.sdk = sdk;
    this.optOutOfResourcePathShortening = optOutOfResourcePathShortening;
    this.optOutOfResourceNameObfuscation = optOutOfResourceNameObfuscation;
    this.throwOnShrinkResources = throwOnShrinkResources;
    this.throwOnProguardApplyDictionary = throwOnProguardApplyDictionary;
    this.throwOnProguardApplyMapping = throwOnProguardApplyMapping;
    this.throwOnResourceConflict = throwOnResourceConflict;
    this.useDataBindingV2 = useDataBindingV2;
    this.useDataBindingAndroidX = useDataBindingAndroidX;
    this.includeProguardLocationReferences = includeProguardLocationReferences;
    this.executionInfo = executionInfo;
  }

  public Label getLabel() {
    return ruleContext.getLabel();
  }

  public ActionConstructionContext getActionConstructionContext() {
    return ruleContext;
  }

  public RuleErrorConsumer getRuleErrorConsumer() {
    return ruleContext;
  }

  public FilesToRunProvider getBusybox() {
    return busybox;
  }

  public AndroidSdkProvider getSdk() {
    return sdk;
  }

  public ImmutableMap<String, String> getExecutionInfo() {
    return executionInfo;
  }

  /*
   * Convenience methods. These are just slightly cleaner ways of doing common tasks.
   */

  /** Builds and registers a {@link SpawnAction.Builder}. */
  public void registerAction(SpawnAction.Builder spawnActionBuilder) {
    registerAction(spawnActionBuilder.build(ruleContext));
  }

  /** Registers an action. */
  public void registerAction(ActionAnalysisMetadata action) {
    ruleContext.registerAction(action);
  }

  public Artifact createOutputArtifact(SafeImplicitOutputsFunction function)
      throws InterruptedException {
    return ruleContext.getImplicitOutputArtifact(function);
  }

  public Artifact getUniqueDirectoryArtifact(String uniqueDirectorySuffix, String relative) {
    return ruleContext.getUniqueDirectoryArtifact(uniqueDirectorySuffix, relative);
  }

  public Artifact getUniqueDirectoryArtifact(String uniqueDirectorySuffix, PathFragment relative) {
    return ruleContext.getUniqueDirectoryArtifact(uniqueDirectorySuffix, relative);
  }

  public PathFragment getUniqueDirectory(PathFragment fragment) {
    return ruleContext.getUniqueDirectory(fragment);
  }

  public ArtifactRoot getBinOrGenfilesDirectory() {
    return ruleContext.getBinOrGenfilesDirectory();
  }

  public PathFragment getPackageDirectory() {
    return ruleContext.getPackageDirectory();
  }

  public AndroidConfiguration getAndroidConfig() {
    return ruleContext.getConfiguration().getFragment(AndroidConfiguration.class);
  }

  @Nullable
  public BazelAndroidConfiguration getBazelAndroidConfig() {
    return ruleContext.getConfiguration().getFragment(BazelAndroidConfiguration.class);
  }

  /** Indicates whether Busybox actions should be passed the "--debug" flag */
  public boolean useDebug() {
    return getActionConstructionContext().getConfiguration().getCompilationMode() != OPT;
  }

  public boolean isPersistentBusyboxToolsEnabled() {
    return persistentBusyboxToolsEnabled;
  }

  public boolean optOutOfResourcePathShortening() {
    return optOutOfResourcePathShortening;
  }

  public boolean optOutOfResourceNameObfuscation() {
    return optOutOfResourceNameObfuscation;
  }

  public boolean throwOnShrinkResources() {
    return throwOnShrinkResources;
  }

  public boolean throwOnProguardApplyDictionary() {
    return throwOnProguardApplyDictionary;
  }

  public boolean throwOnProguardApplyMapping() {
    return throwOnProguardApplyMapping;
  }

  public boolean throwOnResourceConflict() {
    return throwOnResourceConflict;
  }

  public boolean useDataBindingV2() {
    return useDataBindingV2;
  }

  public boolean useDataBindingAndroidX() {
    return useDataBindingAndroidX;
  }

  public boolean includeProguardLocationReferences() {
    return includeProguardLocationReferences;
  }

  public boolean annotateRFieldsFromTransitiveDeps() {
    return ruleContext.getFeatures().contains(ANNOTATE_R_FIELDS_FROM_TRANSITIVE_DEPS);
  }

  boolean omitTransitiveResourcesFromAndroidRClasses() {
    return ruleContext.getFeatures().contains(OMIT_TRANSITIVE_RESOURCES_FROM_ANDROID_R_CLASSES);
  }

  /** Returns true if the context dictates that resource shrinking should be performed. */
  boolean useResourceShrinking(boolean hasProguardSpecs) {
    return isResourceShrinkingEnabled() && hasProguardSpecs;
  }

  /**
   * Returns true if the context dictates that resource shrinking is enabled. This doesn't
   * necessarily mean that shrinking should be performed - for that, use {@link
   * #useResourceShrinking(boolean)}, which calls this.
   */
  boolean isResourceShrinkingEnabled() {
    if (!ruleContext.attributes().has("shrink_resources")) {
      return false;
    }

    TriState state = ruleContext.attributes().get("shrink_resources", BuildType.TRISTATE);
    if (state == TriState.AUTO) {
      state = getAndroidConfig().useAndroidResourceShrinking() ? TriState.YES : TriState.NO;
    }

    return state == TriState.YES;
  }

  /**
   * Returns {@code true} if resource shrinking should be performed. This should be true when the
   * resource cycle shrinking flag is enabled, resource shrinking itself is enabled, and the build
   * is ProGuarded/optimized. The last condition is important because resource cycle shrinking
   * generates non-final fields that are not inlined by javac. In non-optimized builds, these can
   * noticeably increase Apk size.
   */
  boolean shouldShrinkResourceCycles(RuleErrorConsumer errorConsumer, boolean shrinkResources) {
    boolean isProguarded =
        ruleContext.attributes().has(ProguardHelper.PROGUARD_SPECS, BuildType.LABEL_LIST)
            && !ruleContext
                .getPrerequisiteArtifacts(ProguardHelper.PROGUARD_SPECS)
                .list()
                .isEmpty();
    return isProguarded && getAndroidConfig().useAndroidResourceCycleShrinking() && shrinkResources;
  }

  boolean useResourcePathShortening() {
    // Use resource path shortening iff:
    //   1) --experimental_android_resource_path_shortening
    //   2) -c opt
    //   3) Not opting out by being on allowlist named allow_raw_access_to_resource_paths
    return getAndroidConfig().useAndroidResourcePathShortening()
        && getActionConstructionContext().getConfiguration().getCompilationMode() == OPT
        && !optOutOfResourcePathShortening;
  }

  boolean useResourceNameObfuscation(boolean hasProguardSpecs) {
    // Use resource name obfuscation iff:
    //   1) --experimental_android_resource_name_obfuscation or feature enabled for rule's package
    //   2) resource shrinking is on (implying proguard specs are present)
    //   3) Not opting out by being on allowlist named allow_resource_name_obfuscation_opt_out
    return (getAndroidConfig().useAndroidResourceNameObfuscation()
            || ruleContext.getFeatures().contains(FEATURE_RESOURCE_NAME_OBFUSCATION))
        && useResourceShrinking(hasProguardSpecs)
        && !optOutOfResourceNameObfuscation;
  }
}
