// 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 com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleErrorConsumer;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;

/** Wraps merged Android resources. */
public class MergedAndroidResources extends ParsedAndroidResources {
  private final Artifact mergedResources;
  private final Artifact classJar;
  @Nullable private final Artifact aapt2RTxt;
  @Nullable private final Artifact dataBindingInfoZip;
  private final ResourceDependencies resourceDependencies;
  /**
   * The processed manifest.
   *
   * <p>TODO(b/30817309): Just use the manifest inherited from {@link ParsedAndroidResources} once
   * the legacy manifest merger is removed.
   */
  private final ProcessedAndroidManifest manifest;

  public static MergedAndroidResources mergeFrom(
      AndroidDataContext dataContext,
      ParsedAndroidResources parsed,
      ResourceDependencies resourceDeps)
      throws InterruptedException {

    Preconditions.checkNotNull(
        parsed.getCompiledSymbols(),
        "Should not use compiled merge if no compiled symbols are available!");

    AndroidResourceMergingActionBuilder builder =
        new AndroidResourceMergingActionBuilder()
            .setJavaPackage(parsed.getJavaPackage())
            .withDependencies(resourceDeps)
            .setThrowOnResourceConflict(dataContext.throwOnResourceConflict())
            .setAnnotateRFieldsFromTransitiveDeps(dataContext.annotateRFieldsFromTransitiveDeps())
            .setOmitTransitiveDependenciesFromAndroidRClasses(
                dataContext.omitTransitiveResourcesFromAndroidRClasses());

    if (dataContext.getAndroidConfig().useRTxtFromMergedResources()) {
      builder.setAapt2RTxtOut(
          dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_R_TXT));
    }

    return builder
        .setManifestOut(
            dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST))
        .setClassJarOut(
            dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
        .build(dataContext, parsed);
  }

  public static MergedAndroidResources of(
      ParsedAndroidResources parsed,
      Artifact mergedResources,
      Artifact classJar,
      Artifact aapt2RTxt,
      @Nullable Artifact dataBindingInfoZip,
      ResourceDependencies resourceDependencies,
      ProcessedAndroidManifest manifest) {
    return new MergedAndroidResources(
        parsed,
        mergedResources,
        classJar,
        aapt2RTxt,
        dataBindingInfoZip,
        resourceDependencies,
        manifest);
  }

  MergedAndroidResources(MergedAndroidResources other) {
    this(
        other,
        other.mergedResources,
        other.classJar,
        other.aapt2RTxt,
        other.dataBindingInfoZip,
        other.resourceDependencies,
        other.manifest);
  }

  protected MergedAndroidResources(
      ParsedAndroidResources other,
      Artifact mergedResources,
      Artifact classJar,
      Artifact aapt2RTxt,
      @Nullable Artifact dataBindingInfoZip,
      ResourceDependencies resourceDependencies,
      ProcessedAndroidManifest manifest) {
    super(other, manifest);
    this.mergedResources = mergedResources;
    this.classJar = classJar;
    this.aapt2RTxt = aapt2RTxt;
    this.dataBindingInfoZip = dataBindingInfoZip;
    this.resourceDependencies = resourceDependencies;
    this.manifest = manifest;
  }

  /**
   * Gets an Artifact containing a zip of merged resources.
   *
   * <p>If assets were processed together with resources, the zip will also contain merged assets.
   *
   * @deprecated This artifact is produced by an often-expensive action and should not be used if
   *     another option is available. Furthermore, it will be replaced by flat files once we
   *     completely move to aapt2.
   */
  @Deprecated
  public Artifact getMergedResources() {
    return mergedResources;
  }

  public Artifact getClassJar() {
    return classJar;
  }

  @Nullable
  public Artifact getDataBindingInfoZip() {
    return dataBindingInfoZip;
  }

  public Artifact getJavaClassJar() {
    return classJar;
  }

  @Nullable
  Artifact getAapt2RTxt() {
    return aapt2RTxt;
  }

  @Override
  public ProcessedAndroidManifest getStampedManifest() {
    return manifest;
  }

  public ProcessedAndroidManifest getProcessedManifest() {
    return manifest;
  }

  public ResourceDependencies getResourceDependencies() {
    return resourceDependencies;
  }

  /**
   * Validates and packages this rule's resources.
   *
   * <p>See {@link ValidatedAndroidResources#validateFrom(AndroidDataContext,
   * MergedAndroidResources)}. This method is a convenience method for calling that one.
   */
  public ValidatedAndroidResources validate(AndroidDataContext dataContext)
      throws InterruptedException {
    return ValidatedAndroidResources.validateFrom(dataContext, this, ImmutableList.of());
  }

  /**
   * Validates and packages this rule's resources.
   *
   * <p>See {@link ValidatedAndroidResources#validateFrom(AndroidDataContext,
   * MergedAndroidResources)}. This method is a convenience method for calling that one.
   */
  public ValidatedAndroidResources validate(
      AndroidDataContext dataContext, List<Artifact> resApkDeps) throws InterruptedException {
    return ValidatedAndroidResources.validateFrom(dataContext, this, resApkDeps);
  }

  @Override
  public Optional<? extends MergedAndroidResources> maybeFilter(
      RuleErrorConsumer errorConsumer, ResourceFilter resourceFilter, boolean isDependency)
      throws RuleErrorException {
    return super.maybeFilter(errorConsumer, resourceFilter, isDependency)
        .map(
            parsed ->
                MergedAndroidResources.of(
                    parsed,
                    mergedResources,
                    classJar,
                    aapt2RTxt,
                    dataBindingInfoZip,
                    resourceDependencies,
                    manifest));
  }

  @Override
  public boolean equals(Object object) {
    if (!super.equals(object) || !(object instanceof MergedAndroidResources)) {
      return false;
    }

    MergedAndroidResources other = (MergedAndroidResources) object;
    return Objects.equals(mergedResources, other.mergedResources)
        && classJar.equals(other.classJar)
        && Objects.equals(aapt2RTxt, other.aapt2RTxt)
        && Objects.equals(dataBindingInfoZip, other.dataBindingInfoZip)
        && resourceDependencies.equals(other.resourceDependencies);
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        super.hashCode(),
        mergedResources,
        classJar,
        aapt2RTxt,
        dataBindingInfoZip,
        resourceDependencies);
  }
}
