// 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 com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import java.util.Optional;
import javax.annotation.Nullable;

/**
 * Represents a container for the resource dependencies for a given target. This abstraction
 * simplifies the process of managing and exporting the direct and transitive resource dependencies
 * of an android rule, as well as providing type safety.
 *
 * <p>The transitive and direct dependencies are not guaranteed to be disjoint. If a library is
 * included in both the transitive and direct dependencies, it will appear twice. This requires
 * consumers to manage duplicated resources gracefully.
 *
 * <p>TODO(b/76418178): Once resource processing is fully decoupled from asset and manifest
 * processing, remove asset and manifest fields from this class.
 */
@Immutable
public final class ResourceDependencies {
  /**
   * Contains all the transitive resources that are not generated by the direct ancestors of the
   * current rule.
   *
   * @deprecated We are migrating towards storing each type of Artifact in a different NestedSet.
   *     This should allow greater efficiency since we don't need to unroll this NestedSet to get a
   *     particular input. TODO (b/67996945): Complete this migration.
   */
  @Deprecated private final NestedSet<ValidatedAndroidResources> transitiveResourceContainers;

  /**
   * Contains all the direct dependencies of the current target. Since a given direct dependency can
   * act as a "forwarding" library, collecting all the direct resource from it's dependencies and
   * providing them as "direct" dependencies to maintain merge order, this uses a NestedSet to
   * properly maintain ordering and ease of merging.
   *
   * @deprecated Similarly to {@link #transitiveResourceContainers}, we are moving away from storing
   *     ResourceContainer objects here. TODO (b/67996945): Complete this migration.
   */
  @Deprecated private final NestedSet<ValidatedAndroidResources> directResourceContainers;

  /**
   * Transitive resource files for this target.
   *
   * <p>We keep them separate from the {@code transitiveAssets} so that we can filter them.
   */
  private final NestedSet<Artifact> transitiveResources;

  private final NestedSet<Artifact> transitiveManifests;

  private final NestedSet<Artifact> transitiveAapt2RTxt;

  private final NestedSet<Artifact> transitiveSymbolsBin;

  private final NestedSet<Artifact> transitiveCompiledSymbols;

  private final NestedSet<Artifact> transitiveStaticLib;

  private final NestedSet<Artifact> transitiveRTxt;

  /** Whether the resources of the current rule should be treated as neverlink. */
  private final boolean neverlink;

  public static ResourceDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) {
    return fromProviders(
        AndroidCommon.getTransitivePrerequisites(
            ruleContext, Mode.TARGET, AndroidResourcesInfo.PROVIDER),
        neverlink);
  }

  public static ResourceDependencies fromProviders(
      Iterable<AndroidResourcesInfo> providers, boolean neverlink) {
    NestedSetBuilder<ValidatedAndroidResources> transitiveDependencies =
        NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<ValidatedAndroidResources> directDependencies =
        NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveResources = NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveManifests = NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveCompiledSymbols = NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveStaticLib = NestedSetBuilder.naiveLinkOrder();
    NestedSetBuilder<Artifact> transitiveRTxt = NestedSetBuilder.naiveLinkOrder();

    for (AndroidResourcesInfo resources : providers) {
      transitiveDependencies.addTransitive(resources.getTransitiveAndroidResources());
      directDependencies.addTransitive(resources.getDirectAndroidResources());
      transitiveResources.addTransitive(resources.getTransitiveResources());
      transitiveManifests.addTransitive(resources.getTransitiveManifests());
      transitiveAapt2RTxt.addTransitive(resources.getTransitiveAapt2RTxt());
      transitiveSymbolsBin.addTransitive(resources.getTransitiveSymbolsBin());
      transitiveCompiledSymbols.addTransitive(resources.getTransitiveCompiledSymbols());
      transitiveStaticLib.addTransitive(resources.getTransitiveStaticLib());
      transitiveRTxt.addTransitive(resources.getTransitiveRTxt());
    }

    return new ResourceDependencies(
        neverlink,
        transitiveDependencies.build(),
        directDependencies.build(),
        transitiveResources.build(),
        transitiveManifests.build(),
        transitiveAapt2RTxt.build(),
        transitiveSymbolsBin.build(),
        transitiveCompiledSymbols.build(),
        transitiveStaticLib.build(),
        transitiveRTxt.build());
  }

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(this)
        .add("transitiveResourceContainers", transitiveResourceContainers)
        .add("directResourceContainers", directResourceContainers)
        .add("transitiveResources", transitiveResources)
        .add("transitiveManifests", transitiveManifests)
        .add("transitiveAapt2RTxt", transitiveAapt2RTxt)
        .add("transitiveSymbolsBin", transitiveSymbolsBin)
        .add("transitiveCompiledSymbols", transitiveCompiledSymbols)
        .add("transitiveStaticLib", transitiveStaticLib)
        .add("transitiveRTxt", transitiveRTxt)
        .add("neverlink", neverlink)
        .toString();
  }

  /**
   * Creates an empty ResourceDependencies instance. This is used when an AndroidResources rule is
   * the only resource dependency. The most common case is the AndroidTest rule.
   */
  public static ResourceDependencies empty() {
    return new ResourceDependencies(
        false,
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
        NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER));
  }

  private ResourceDependencies(
      boolean neverlink,
      NestedSet<ValidatedAndroidResources> transitiveResourceContainers,
      NestedSet<ValidatedAndroidResources> directResourceContainers,
      NestedSet<Artifact> transitiveResources,
      NestedSet<Artifact> transitiveManifests,
      NestedSet<Artifact> transitiveAapt2RTxt,
      NestedSet<Artifact> transitiveSymbolsBin,
      NestedSet<Artifact> transitiveCompiledSymbols,
      NestedSet<Artifact> transitiveStaticLib,
      NestedSet<Artifact> transitiveRTxt) {
    this.neverlink = neverlink;
    this.transitiveResourceContainers = transitiveResourceContainers;
    this.directResourceContainers = directResourceContainers;
    this.transitiveResources = transitiveResources;
    this.transitiveManifests = transitiveManifests;
    this.transitiveAapt2RTxt = transitiveAapt2RTxt;
    this.transitiveSymbolsBin = transitiveSymbolsBin;
    this.transitiveCompiledSymbols = transitiveCompiledSymbols;
    this.transitiveStaticLib = transitiveStaticLib;
    this.transitiveRTxt = transitiveRTxt;
  }

  /** Returns a copy of this instance with filtered resources. The original object is unchanged. */
  public ResourceDependencies filter(RuleErrorConsumer errorConsumer, ResourceFilter resourceFilter)
      throws RuleErrorException {
    Optional<NestedSet<Artifact>> filteredResources =
        resourceFilter.maybeFilterDependencies(transitiveResources);

    if (!filteredResources.isPresent()) {
      // No filtering was done.
      return this;
    }

    // Note that this doesn't filter any of the dependent artifacts. This
    // means that if any resource changes, the corresponding actions will get
    // re-executed
    return withResources(
        resourceFilter.filterDependencyContainers(errorConsumer, transitiveResourceContainers),
        resourceFilter.filterDependencyContainers(errorConsumer, directResourceContainers),
        filteredResources.get());
  }

  @VisibleForTesting
  ResourceDependencies withResources(
      NestedSet<ValidatedAndroidResources> transitiveResourceContainers,
      NestedSet<ValidatedAndroidResources> directResourceContainers,
      NestedSet<Artifact> transitiveResources) {
    return new ResourceDependencies(
        neverlink,
        transitiveResourceContainers,
        directResourceContainers,
        transitiveResources,
        transitiveManifests,
        transitiveAapt2RTxt,
        transitiveSymbolsBin,
        transitiveCompiledSymbols,
        transitiveStaticLib,
        transitiveRTxt);
  }

  /**
   * Creates a new AndroidResourcesInfo with the supplied ResourceContainer as the direct dep.
   *
   * <p>When a library produces a new resource container the AndroidResourcesInfo should use that
   * container as a the direct dependency for that library. This makes the consuming rule to
   * identify the new container and merge appropriately. The previous direct dependencies are then
   * added to the transitive dependencies.
   *
   * @param newDirectResource The new direct dependency for AndroidResourcesInfo
   * @return A provider with the current resources and label.
   */
  public AndroidResourcesInfo toInfo(ValidatedAndroidResources newDirectResource) {
    if (neverlink) {
      return ResourceDependencies.empty()
          .toInfo(
              newDirectResource.getLabel(),
              newDirectResource.getProcessedManifest(),
              newDirectResource.getRTxt());
    }
    return new AndroidResourcesInfo(
        newDirectResource.getLabel(),
        newDirectResource.getProcessedManifest().toProvider(),
        newDirectResource.getRTxt(),
        NestedSetBuilder.<ValidatedAndroidResources>naiveLinkOrder()
            .addTransitive(transitiveResourceContainers)
            .addTransitive(directResourceContainers)
            .build(),
        NestedSetBuilder.<ValidatedAndroidResources>naiveLinkOrder()
            .add(newDirectResource.export())
            .build(),
        NestedSetBuilder.<Artifact>naiveLinkOrder()
            .addTransitive(transitiveResources)
            .addAll(newDirectResource.getResources())
            .build(),
        withDirectAndTransitive(newDirectResource.getManifest(), transitiveManifests),
        withDirectAndTransitive(newDirectResource.getAapt2RTxt(), transitiveAapt2RTxt),
        withDirectAndTransitive(newDirectResource.getSymbols(), transitiveSymbolsBin),
        withDirectAndTransitive(newDirectResource.getCompiledSymbols(), transitiveCompiledSymbols),
        withDirectAndTransitive(newDirectResource.getStaticLibrary(), transitiveStaticLib),
        withDirectAndTransitive(newDirectResource.getRTxt(), transitiveRTxt));
  }

  /**
   * Create a new AndroidResourcesInfo from the dependencies of this library.
   *
   * <p>When a library doesn't export resources it should simply forward the current transitive and
   * direct resources to the consuming rule. This allows the consuming rule to make decisions about
   * the resource merging as if this library didn't exist.
   *
   * @param label The label of the library exporting this provider.
   * @return A provider with the current resources and label.
   */
  public AndroidResourcesInfo toInfo(
      Label label, ProcessedAndroidManifest manifest, Artifact rTxt) {
    if (neverlink) {
      return ResourceDependencies.empty().toInfo(label, manifest, rTxt);
    }
    return new AndroidResourcesInfo(
        label,
        manifest.toProvider(),
        rTxt,
        transitiveResourceContainers,
        directResourceContainers,
        transitiveResources,
        transitiveManifests,
        transitiveAapt2RTxt,
        transitiveSymbolsBin,
        transitiveCompiledSymbols,
        transitiveStaticLib,
        transitiveRTxt);
  }

  private static NestedSet<Artifact> withDirectAndTransitive(
      @Nullable Artifact direct, NestedSet<Artifact> transitive) {
    NestedSetBuilder<Artifact> builder = NestedSetBuilder.naiveLinkOrder();
    builder.addTransitive(transitive);
    if (direct != null) {
      builder.add(direct);
    }

    return builder.build();
  }

  /**
   * Provides an NestedSet of the direct and transitive resources.
   *
   * @deprecated Rather than accessing the ResourceContainers, use other methods in this class to
   *     get the specific Artifacts you need instead.
   */
  @Deprecated
  public NestedSet<ValidatedAndroidResources> getResourceContainers() {
    return NestedSetBuilder.<ValidatedAndroidResources>naiveLinkOrder()
        .addTransitive(directResourceContainers)
        .addTransitive(transitiveResourceContainers)
        .build();
  }

  /**
   * @deprecated Rather than accessing the ResourceContainers, use other methods in this class to
   *     get the specific Artifacts you need instead.
   */
  @Deprecated
  public NestedSet<ValidatedAndroidResources> getTransitiveResourceContainers() {
    return transitiveResourceContainers;
  }

  /**
   * @deprecated Rather than accessing the ResourceContainers, use other methods in this class to
   *     get the specific Artifacts you need instead.
   */
  @Deprecated
  public NestedSet<ValidatedAndroidResources> getDirectResourceContainers() {
    return directResourceContainers;
  }

  public NestedSet<Artifact> getTransitiveResources() {
    return transitiveResources;
  }

  public NestedSet<Artifact> getTransitiveManifests() {
    return transitiveManifests;
  }

  public NestedSet<Artifact> getTransitiveAapt2RTxt() {
    return transitiveAapt2RTxt;
  }

  public NestedSet<Artifact> getTransitiveSymbolsBin() {
    return transitiveSymbolsBin;
  }

  /**
   * @return The transitive closure of compiled symbols. Compiled symbols are zip files containing
   *     the compiled resource output of aapt2 compile
   */
  public NestedSet<Artifact> getTransitiveCompiledSymbols() {
    return transitiveCompiledSymbols;
  }

  public NestedSet<Artifact> getTransitiveStaticLib() {
    return transitiveStaticLib;
  }

  public NestedSet<Artifact> getTransitiveRTxt() {
    return transitiveRTxt;
  }
}
