// 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.android.resources.ResourceFolderType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * The collected resources artifacts and roots.
 *
 * <p>This is used to encapsulate the logic and the data associated with the resources derived from
 * an appropriate android rule in a reusable instance.
 */
public class AndroidResources {
  private static final String DEFAULT_RESOURCES_ATTR = "resource_files";

  public static final String[] RESOURCES_ATTRIBUTES =
      new String[] {
        "manifest",
        DEFAULT_RESOURCES_ATTR,
        "local_resource_files",
        "assets",
        "assets_dir",
        "inline_constants",
        "exports_manifest"
      };

  /** Set of allowable android directories prefixes. */
  public static final ImmutableSet<String> RESOURCE_DIRECTORY_TYPES =
      Arrays.stream(ResourceFolderType.values())
          .map(ResourceFolderType::getName)
          .collect(ImmutableSet.toImmutableSet());

  public static final String INCORRECT_RESOURCE_LAYOUT_MESSAGE =
      String.format(
          "'%%s' is not in the expected resource directory structure of "
              + "<resource directory>/{%s}/<file>",
          Joiner.on(',').join(RESOURCE_DIRECTORY_TYPES));

  /**
   * Determines if the attributes contain resource and asset attributes.
   *
   * @deprecated We are moving towards processing Android assets, resources, and manifests
   *     separately. Use a separate method that just checks the attributes you need.
   */
  @Deprecated
  public static boolean definesAndroidResources(AttributeMap attributes) {
    for (String attribute : RESOURCES_ATTRIBUTES) {
      if (attributes.isAttributeValueExplicitlySpecified(attribute)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Checks validity of a RuleContext to produce Android resources, assets, and manifests.
   *
   * @throws RuleErrorException if the RuleContext is invalid. Accumulated errors will be available
   *     via {@code ruleContext}
   * @deprecated We are moving towards processing Android assets, resources, and manifests
   *     separately. Use a separate method that just checks the values you need.
   */
  @Deprecated
  public static void validateRuleContext(RuleContext ruleContext) throws RuleErrorException {
    AndroidAssets.validateAssetsAndAssetsDir(ruleContext);
    validateNoAndroidResourcesInSources(ruleContext);
    validateManifest(ruleContext);
  }

  public static boolean decoupleDataProcessing(RuleContext ruleContext) {
    return AndroidCommon.getAndroidConfig(ruleContext).decoupleDataProcessing();
  }

  /**
   * Validates that there are no targets with resources in the srcs, as they should not be used with
   * the Android data logic.
   */
  private static void validateNoAndroidResourcesInSources(RuleContext ruleContext)
      throws RuleErrorException {
    Iterable<AndroidResourcesInfo> resources =
        ruleContext.getPrerequisites("srcs", Mode.TARGET, AndroidResourcesInfo.PROVIDER);
    for (AndroidResourcesInfo info : resources) {
      ruleContext.throwWithAttributeError(
          "srcs",
          String.format("srcs should not contain label with resources %s", info.getLabel()));
    }
  }

  private static void validateManifest(RuleContext ruleContext) throws RuleErrorException {
    if (ruleContext.getPrerequisiteArtifact("manifest", Mode.TARGET) == null) {
      ruleContext.throwWithAttributeError(
          "manifest", "manifest is required when resource_files or assets are defined.");
    }
  }

  public static AndroidResources from(RuleContext ruleContext, String resourcesAttr)
      throws RuleErrorException {
    if (!hasLocalResourcesAttributes(ruleContext)) {
      return empty();
    }

    return from(
        ruleContext,
        ruleContext.getPrerequisites(resourcesAttr, Mode.TARGET, FileProvider.class),
        resourcesAttr);
  }

  public static AndroidResources from(
      RuleErrorConsumer errorConsumer,
      Iterable<FileProvider> resourcesTargets,
      String resourcesAttr)
      throws RuleErrorException {
    return forResources(errorConsumer, getResources(resourcesTargets), resourcesAttr);
  }

  /** Returns an {@link AndroidResources} for a list of resource artifacts. */
  @VisibleForTesting
  public static AndroidResources forResources(
      RuleErrorConsumer ruleErrorConsumer, ImmutableList<Artifact> resources, String resourcesAttr)
      throws RuleErrorException {
    return new AndroidResources(
        resources, getResourceRoots(ruleErrorConsumer, resources, resourcesAttr));
  }

  /**
   * TODO(b/76218640): Whether local resources are built into a target should depend on that
   * target's resource attribute ("resource_files" in general, but local_resource_files for
   * android_test), not any other attributes.
   */
  private static boolean hasLocalResourcesAttributes(RuleContext ruleContext) {
    return ruleContext.attributes().has("assets") || ruleContext.attributes().has("resource_files");
  }

  static AndroidResources empty() {
    return new AndroidResources(ImmutableList.of(), ImmutableList.of());
  }

  /**
   * Creates a {@link AndroidResources} containing all the resources in directory artifacts, for use
   * with AarImport rules.
   *
   * <p>In general, {@link #from(RuleContext, String)} should be used instead, but it can't be for
   * AarImport since we don't know about its individual assets at analysis time. No transitive
   * resources will be included in the container produced by this method.
   *
   * @param resourcesDir the tree artifact containing a {@code res/} directory
   */
  static AndroidResources forAarImport(SpecialArtifact resourcesDir) {
    Preconditions.checkArgument(resourcesDir.isTreeArtifact());
    return new AndroidResources(
        ImmutableList.of(resourcesDir),
        ImmutableList.of(resourcesDir.getExecPath().getChild("res")));
  }

  /**
   * Inner method for adding resource roots to a collection. May fail and report to the {@link
   * RuleErrorConsumer} if the input is invalid.
   *
   * @param file the file to add the resource directory for
   * @param lastFile the last file this method was called on. May be null if this is the first call
   *     for this set of resources.
   * @param lastResourceDir the resource directory of the last file, as returned by the most recent
   *     call to this method, or null if this is the first call.
   * @param resourceRoots the collection to add resources to
   * @param resourcesAttr the attribute used to refer to resources. While we're moving towards
   *     "resource_files" everywhere, there are still uses of other attributes for different kinds
   *     of rules.
   * @param ruleErrorConsumer for reporting errors
   * @return the resource root of {@code file}.
   * @throws RuleErrorException if the current resource has no resource directory or if it is
   *     incompatible with {@code lastResourceDir}. An error will also be reported to the {@link
   *     RuleErrorConsumer} in this case.
   */
  private static PathFragment addResourceDir(
      Artifact file,
      @Nullable Artifact lastFile,
      @Nullable PathFragment lastResourceDir,
      Set<PathFragment> resourceRoots,
      String resourcesAttr,
      RuleErrorConsumer ruleErrorConsumer)
      throws RuleErrorException {
    PathFragment resourceDir = findResourceDir(file);
    if (resourceDir == null) {
      ruleErrorConsumer.attributeError(
          resourcesAttr,
          String.format(INCORRECT_RESOURCE_LAYOUT_MESSAGE, file.getRootRelativePath()));
      throw new RuleErrorException();
    }

    if (lastResourceDir != null && !resourceDir.equals(lastResourceDir)) {
      ruleErrorConsumer.attributeError(
          resourcesAttr,
          String.format(
              "'%s' (generated by '%s') is not in the same directory '%s' (derived from %s)."
                  + " All resources must share a common directory.",
              file.getRootRelativePath(),
              file.getArtifactOwner().getLabel(),
              lastResourceDir,
              lastFile.getRootRelativePath()));
      throw new RuleErrorException();
    }

    PathFragment packageFragment =
        file.getArtifactOwner().getLabel().getPackageIdentifier().getSourceRoot();
    PathFragment packageRelativePath = file.getRootRelativePath().relativeTo(packageFragment);
    try {
      PathFragment path = file.getExecPath();
      resourceRoots.add(
          path.subFragment(
              0,
              path.segmentCount() - segmentCountAfterAncestor(resourceDir, packageRelativePath)));
    } catch (IllegalArgumentException e) {
      ruleErrorConsumer.attributeError(
          resourcesAttr,
          String.format(
              "'%s' (generated by '%s') is not under the directory '%s' (derived from %s).",
              file.getRootRelativePath(),
              file.getArtifactOwner().getLabel(),
              packageRelativePath,
              file.getRootRelativePath()));
      throw new RuleErrorException();
    }
    return resourceDir;
  }

  /**
   * Finds and validates the resource directory PathFragment from the artifact Path.
   *
   * <p>If the artifact is not a Fileset, the resource directory is presumed to be the second
   * directory from the end. Filesets are expect to have the last directory as the resource
   * directory.
   */
  public static PathFragment findResourceDir(Artifact artifact) {
    PathFragment fragment = artifact.getExecPath();
    int segmentCount = fragment.segmentCount();
    if (segmentCount < 3) {
      return null;
    }
    // TODO(bazel-team): Expand Fileset to verify, or remove Fileset as an option for resources.
    if (artifact.isFileset() || artifact.isTreeArtifact()) {
      return fragment.subFragment(segmentCount - 1);
    }

    // Check the resource folder type layout.
    // get the prefix of the parent folder of the fragment.
    String parentDirectory = fragment.getSegment(segmentCount - 2);
    int dashIndex = parentDirectory.indexOf('-');
    String androidFolder =
        dashIndex == -1 ? parentDirectory : parentDirectory.substring(0, dashIndex);
    if (!RESOURCE_DIRECTORY_TYPES.contains(androidFolder)) {
      return null;
    }

    return fragment.subFragment(segmentCount - 3, segmentCount - 2);
  }

  private static int segmentCountAfterAncestor(PathFragment ancestor, PathFragment path) {
    String cutAtSegment = ancestor.getSegment(ancestor.segmentCount() - 1);
    int index = -1;
    List<String> segments = path.getSegments();
    for (int i = segments.size() - 1; i >= 0; i--) {
      if (segments.get(i).equals(cutAtSegment)) {
        index = i;
        break;
      }
    }
    if (index == -1) {
      throw new IllegalArgumentException("PathFragment " + path + " is not beneath " + ancestor);
    }
    return segments.size() - index - 1;
  }

  private final ImmutableList<Artifact> resources;
  private final ImmutableList<PathFragment> resourceRoots;

  AndroidResources(AndroidResources other) {
    this(other.resources, other.resourceRoots);
  }

  @VisibleForTesting
  public AndroidResources(
      ImmutableList<Artifact> resources, ImmutableList<PathFragment> resourceRoots) {
    this.resources = resources;
    this.resourceRoots = resourceRoots;
  }

  private static ImmutableList<Artifact> getResources(Iterable<FileProvider> targets) {
    ImmutableList.Builder<Artifact> builder = ImmutableList.builder();
    for (FileProvider target : targets) {
      builder.addAll(target.getFilesToBuild());
    }

    return builder.build();
  }

  public ImmutableList<Artifact> getResources() {
    return resources;
  }

  /**
   * Gets the roots of some resources.
   *
   * @return a list of roots, or an empty list of the passed resources cannot all be contained in a
   *     single {@link AndroidResources}. If that's the case, it will be reported to the {@link
   *     RuleErrorConsumer}.
   */
  @VisibleForTesting
  static ImmutableList<PathFragment> getResourceRoots(
      RuleErrorConsumer ruleErrorConsumer, Iterable<Artifact> files, String resourcesAttr)
      throws RuleErrorException {
    Artifact lastFile = null;
    PathFragment lastResourceDir = null;
    Set<PathFragment> resourceRoots = new LinkedHashSet<>();
    for (Artifact file : files) {
      PathFragment resourceDir =
          addResourceDir(
              file, lastFile, lastResourceDir, resourceRoots, resourcesAttr, ruleErrorConsumer);
      lastFile = file;
      lastResourceDir = resourceDir;
    }

    return ImmutableList.copyOf(resourceRoots);
  }

  public ImmutableList<PathFragment> getResourceRoots() {
    return resourceRoots;
  }

  /**
   * Filters this object, assuming it contains the resources of the current target.
   *
   * <p>If this object contains the resources from a dependency of this target, use {@link
   * #maybeFilter(RuleErrorConsumer, ResourceFilter, boolean)} instead.
   *
   * @return a filtered {@link AndroidResources} object. If no filtering was done, this object will
   *     be returned.
   */
  public AndroidResources filterLocalResources(
      RuleErrorConsumer errorConsumer, ResourceFilter resourceFilter) throws RuleErrorException {
    Optional<? extends AndroidResources> filtered =
        maybeFilter(errorConsumer, resourceFilter, /* isDependency = */ false);
    return filtered.isPresent() ? filtered.get() : this;
  }

  /**
   * Filters this object.
   *
   * @return an optional wrapping a new {@link AndroidResources} with resources filtered by the
   *     passed {@link ResourceFilter}, or {@link Optional#empty()} if no resources should be
   *     filtered.
   */
  public Optional<? extends AndroidResources> maybeFilter(
      RuleErrorConsumer errorConsumer, ResourceFilter resourceFilter, boolean isDependency)
      throws RuleErrorException {
    Optional<ImmutableList<Artifact>> filtered =
        resourceFilter.maybeFilter(resources, /* isDependency= */ isDependency);

    if (!filtered.isPresent()) {
      // Nothing was filtered out
      return Optional.empty();
    }

    return Optional.of(
        new AndroidResources(
            filtered.get(),
            getResourceRoots(errorConsumer, filtered.get(), DEFAULT_RESOURCES_ATTR)));
  }

  /** Parses these resources. */
  public ParsedAndroidResources parse(
      RuleContext ruleContext,
      StampedAndroidManifest manifest,
      boolean enableDataBinding,
      AndroidAaptVersion aaptVersion)
      throws InterruptedException {
    return ParsedAndroidResources.parseFrom(
        ruleContext, this, manifest, enableDataBinding, aaptVersion);
  }

  /**
   * Performs the complete resource processing pipeline - parsing, merging, and validation - on
   * these resources.
   */
  public ValidatedAndroidResources process(
      RuleContext ruleContext, StampedAndroidManifest manifest, boolean neverlink)
      throws RuleErrorException, InterruptedException {
    boolean enableDataBinding = DataBinding.isEnabled(ruleContext);
    AndroidAaptVersion aaptVersion = AndroidAaptVersion.chooseTargetAaptVersion(ruleContext);
    ResourceDependencies resourceDeps = ResourceDependencies.fromRuleDeps(ruleContext, neverlink);

    return parse(ruleContext, manifest, enableDataBinding, aaptVersion)
        .merge(ruleContext, resourceDeps, enableDataBinding, aaptVersion)
        .validate(ruleContext, aaptVersion);
  }

  @Override
  public boolean equals(Object object) {
    if (object == null || getClass() != object.getClass()) {
      return false;
    }

    AndroidResources other = (AndroidResources) object;
    return resources.equals(other.resources) && resourceRoots.equals(other.resourceRoots);
  }

  @Override
  public int hashCode() {
    return Objects.hash(resources, resourceRoots);
  }
}
