// 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.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineItem.ParametrizedMapFn;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.CompileTimeConstant;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * Factory for functions to convert a {@code T} to a commandline argument. Uses a certain convention
 * for commandline arguments (e.g., separators, and ordering of container elements).
 *
 * <p>Should only need to be created statically, and in limited quantity.
 */
public class AndroidDataConverter<T> extends ParametrizedMapFn<T> {

  /**
   * Converts parsed Android resources to the "SerializedAndroidData" format used by the Android
   * data processing actions.
   */
  @SerializationConstant
  static final AndroidDataConverter<ParsedAndroidResources> PARSED_RESOURCE_CONVERTER =
      AndroidDataConverter.<ParsedAndroidResources>builder(JoinerType.SEMICOLON_AMPERSAND)
          .withRoots(ParsedAndroidResources::getResourceRoots)
          .withEmpty()
          .withLabel(ParsedAndroidResources::getLabel)
          .maybeWithArtifact(ParsedAndroidResources::getSymbols)
          .build();

  /**
   * Converts compiled Android resources to the "SerializedAndroidData" format used by the Android
   * data processing actions.
   */
  @SerializationConstant
  static final AndroidDataConverter<ParsedAndroidResources> COMPILED_RESOURCE_CONVERTER =
      AndroidDataConverter.<ParsedAndroidResources>builder(JoinerType.SEMICOLON_AMPERSAND)
          .withEmpty() // resourceDirs
          .withEmpty() // assetDirs
          .withLabel(ParsedAndroidResources::getLabel)
          .maybeWithArtifact(ParsedAndroidResources::getCompiledSymbols)
          .build();

  /**
   * Converts processed Android resources produced by aapt to the "DependencyAndroidData" format
   * used by the Android data processing actions.
   */
  @SerializationConstant
  static final AndroidDataConverter<ValidatedAndroidResources>
      AAPT_RESOURCES_AND_MANIFEST_CONVERTER =
          AndroidDataConverter.<ValidatedAndroidResources>builder(JoinerType.COLON_COMMA)
              .withRoots(ValidatedAndroidResources::getResourceRoots)
              .withEmpty()
              .withArtifact(ValidatedAndroidResources::getManifest)
              .maybeWithArtifact(ValidatedAndroidResources::getRTxt)
              .maybeWithArtifact(ValidatedAndroidResources::getSymbols)
              .build();

  /**
   * Converts processed Android resources produced by aapt2 to the "DependencyAndroidData" format
   * used by the Android data processing actions.
   */
  @SerializationConstant
  static final AndroidDataConverter<ValidatedAndroidResources>
      AAPT2_RESOURCES_AND_MANIFEST_CONVERTER =
          AndroidDataConverter.<ValidatedAndroidResources>builder(JoinerType.COLON_COMMA)
              .withRoots(ValidatedAndroidResources::getResourceRoots)
              .withEmpty()
              .withArtifact(ValidatedAndroidResources::getManifest)
              .maybeWithArtifact(ValidatedAndroidResources::getAapt2RTxt)
              .maybeWithArtifact(ValidatedAndroidResources::getCompiledSymbols)
              .maybeWithArtifact(ValidatedAndroidResources::getSymbols)
              .build();

  /**
   * Converts parsed Android assets to the "SerializedAndroidData" format used by the Android data
   * processing actions.
   */
  @SerializationConstant
  static final AndroidDataConverter<ParsedAndroidAssets> PARSED_ASSET_CONVERTER =
      AndroidDataConverter.<ParsedAndroidAssets>builder(JoinerType.SEMICOLON_AMPERSAND)
          .withEmpty()
          .withRoots(ParsedAndroidAssets::getAssetRoots)
          .withLabel(ParsedAndroidAssets::getLabel)
          .maybeWithArtifact(ParsedAndroidAssets::getSymbols)
          .build();

  /**
   * Converts compiled Android assets to the "SerializedAndroidData" format used by the Android data
   * processing actions.
   */
  @SerializationConstant
  static final AndroidDataConverter<ParsedAndroidAssets> COMPILED_ASSET_CONVERTER =
      AndroidDataConverter.<ParsedAndroidAssets>builder(JoinerType.SEMICOLON_AMPERSAND)
          .withEmpty()
          .withRoots(ParsedAndroidAssets::getAssetRoots)
          .withLabel(ParsedAndroidAssets::getLabel)
          .maybeWithArtifact(ParsedAndroidAssets::getCompiledSymbols)
          .build();

  /** Indicates the type of joiner between options expected by the command line. */
  public enum JoinerType {
    COLON_COMMA(":", ","),
    SEMICOLON_AMPERSAND(";", "&");

    private final String itemSeparator;
    private final String listSeparator;

    JoinerType(String itemSeparator, String listSeparator) {
      this.itemSeparator = itemSeparator;
      this.listSeparator = listSeparator;
    }

    private String escape(String string) {
      return string
          .replace(itemSeparator, "\\" + itemSeparator)
          .replace(listSeparator, "\\" + listSeparator);
    }
  }

  private final ImmutableList<Function<T, String>> suppliers;
  private final JoinerType joinerType;

  private AndroidDataConverter(
      ImmutableList<Function<T, String>> suppliers, JoinerType joinerType) {
    this.suppliers = suppliers;
    this.joinerType = joinerType;
  }

  // We must override equals and hashCode as per the contract of ParametrizedMapFn, but we
  // statically create a very small number of these objects, so we know that reference equality is
  // enough.
  @Override
  public boolean equals(Object obj) {
    return this == obj;
  }

  @Override
  public int hashCode() {
    return System.identityHashCode(this);
  }

  @Override
  public int maxInstancesAllowed() {
    // This is the max number of resource converters we expect to statically
    // construct for any given blaze instance.
    // Do not increase recklessly.
    return 10;
  }

  @Override
  public void expandToCommandLine(T t, Consumer<String> args) {
    args.accept(map(t));
  }

  public String map(T t) {
    return suppliers.stream()
        .map(s -> s.apply(t))
        .collect(Collectors.joining(joinerType.itemSeparator));
  }

  /**
   * Creates a builder for a new {@link AndroidDataConverter}.
   *
   * <p>Because of how Bazel handles these objects, call this method *only* as part of creating a
   * static final field.
   *
   * <p>Additionally, the resulting {@link AndroidDataConverter} object should be annotated with
   * {@link AutoCodec} (and, if relevant, {@link
   * com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization}.
   */
  public static <T> Builder<T> builder(JoinerType joinerType) {
    return new Builder<>(joinerType);
  }

  public VectorArg<String> getVectorArg(NestedSet<? extends T> values) {
    return VectorArg.join(joinerType.listSeparator).each(values).mapped(this);
  }

  public VectorArg<String> getVectorArgForEach(
      @CompileTimeConstant String arg, NestedSet<? extends T> values) {
    return VectorArg.addBefore(arg).each(values).mapped(this);
  }

  static class Builder<T> {
    private final ImmutableList.Builder<Function<T, String>> inner = ImmutableList.builder();
    private final JoinerType joinerType;

    private Builder(JoinerType joinerType) {
      this.joinerType = joinerType;
    }

    Builder<T> withRoots(Function<T, ImmutableList<PathFragment>> rootsFunction) {
      return with(t -> rootsToString(rootsFunction.apply(t)));
    }

    Builder<T> withArtifact(Function<T, Artifact> artifactFunction) {
      return with(t -> artifactFunction.apply(t).getExecPathString());
    }

    Builder<T> withEmpty() {
      return with(t -> "");
    }

    Builder<T> maybeWithArtifact(Function<T, Artifact> nullableArtifactFunction) {
      return with(
          t -> {
            @Nullable Artifact artifact = nullableArtifactFunction.apply(t);
            return artifact == null ? "" : artifact.getExecPathString();
          });
    }

    Builder<T> withLabel(Function<T, Label> labelFunction) {
      // Escape labels, since they are known to contain separating characters (specifically, ':').
      // Anonymous inner class for serialization.
      return with(t -> joinerType.escape(labelFunction.apply(t).toString()));
    }

    @CanIgnoreReturnValue
    Builder<T> with(Function<T, String> stringFunction) {
      inner.add(stringFunction);
      return this;
    }

    AndroidDataConverter<T> build() {
      return new AndroidDataConverter<>(inner.build(), joinerType);
    }
  }

  @VisibleForTesting
  public static String rootsToString(ImmutableList<PathFragment> roots) {
    return roots.stream().map(PathFragment::toString).collect(Collectors.joining("#"));
  }
}
