// 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.vfs.PathFragment;
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.
   */
  @AutoCodec
  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.
   */
  @AutoCodec
  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.
   */
  @AutoCodec
  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.
   */
  @AutoCodec
  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.
   */
  @AutoCodec
  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.
   */
  @AutoCodec
  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()));
    }

    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("#"));
  }
}
