// 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.android;

import com.android.builder.core.VariantType;
import com.android.manifmerger.ManifestMerger2;
import com.android.manifmerger.ManifestMerger2.MergeType;
import com.android.repository.Revision;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.android.aapt2.CompiledResources;
import com.google.devtools.build.android.aapt2.StaticLibrary;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.EnumConverter;
import com.google.devtools.common.options.OptionsParsingException;
import java.io.File;
import java.lang.reflect.ParameterizedType;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Some convenient converters used by android actions. Note: These are specific to android actions.
 */
public final class Converters {
  private static final Converter<String> IDENTITY_CONVERTER =
      new Converter<String>() {
        @Override
        public String convert(String input) {
          return input;
        }

        @Override
        public String getTypeDescription() {
          return "a string";
        }
      };

  /**
   * Converter for {@link UnvalidatedAndroidData}. Relies on {@code
   * UnvalidatedAndroidData#valueOf(String)} to perform conversion and validation.
   */
  public static class UnvalidatedAndroidDataConverter implements Converter<UnvalidatedAndroidData> {

    @Override
    public UnvalidatedAndroidData convert(String input) throws OptionsParsingException {
      try {
        return UnvalidatedAndroidData.valueOf(input);
      } catch (IllegalArgumentException e) {
        throw new OptionsParsingException(
            String.format("invalid UnvalidatedAndroidData: %s", e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "unvalidated android data in the format " + UnvalidatedAndroidData.EXPECTED_FORMAT;
    }
  }

  /** Converter for {@link UnvalidatedAndroidDirectories}. */
  public static class UnvalidatedAndroidDirectoriesConverter
      implements Converter<UnvalidatedAndroidDirectories> {

    @Override
    public UnvalidatedAndroidDirectories convert(String input) throws OptionsParsingException {
      try {
        return UnvalidatedAndroidDirectories.valueOf(input);
      } catch (IllegalArgumentException e) {
        throw new OptionsParsingException(
            String.format("invalid UnvalidatedAndroidDirectories: %s", e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "unvalidated android directories in the format "
          + UnvalidatedAndroidDirectories.EXPECTED_FORMAT;
    }
  }

  /**
   * Converter for a list of {@link DependencyAndroidData}. Relies on {@code
   * DependencyAndroidData#valueOf(String)} to perform conversion and validation.
   */
  public static class DependencyAndroidDataListConverter
      implements Converter<List<DependencyAndroidData>> {

    @Override
    public List<DependencyAndroidData> convert(String input) throws OptionsParsingException {
      if (input.isEmpty()) {
        return ImmutableList.of();
      }
      try {
        ImmutableList.Builder<DependencyAndroidData> builder = ImmutableList.builder();
        for (String item : input.split(",")) {
          builder.add(DependencyAndroidData.valueOf(item));
        }
        return builder.build();
      } catch (IllegalArgumentException e) {
        throw new OptionsParsingException(
            String.format("invalid DependencyAndroidData: %s", e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "a list of dependency android data in the format "
          + DependencyAndroidData.EXPECTED_FORMAT
          + "[,...]";
    }
  }

  /** Converter for a {@link SerializedAndroidData}. */
  public static class SerializedAndroidDataConverter implements Converter<SerializedAndroidData> {

    @Override
    public SerializedAndroidData convert(String input) throws OptionsParsingException {
      try {
        return SerializedAndroidData.valueOf(input);
      } catch (IllegalArgumentException e) {
        throw new OptionsParsingException(
            String.format("invalid SerializedAndroidData: %s", e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "preparsed android data in the format " + SerializedAndroidData.EXPECTED_FORMAT;
    }
  }

  /** Converter for a list of {@link SerializedAndroidData}. */
  public static class SerializedAndroidDataListConverter
      implements Converter<List<SerializedAndroidData>> {

    @Override
    public List<SerializedAndroidData> convert(String input) throws OptionsParsingException {
      if (input.isEmpty()) {
        return ImmutableList.of();
      }
      try {
        ImmutableList.Builder<SerializedAndroidData> builder = ImmutableList.builder();
        for (String entry : input.split("&")) {
          builder.add(SerializedAndroidData.valueOf(entry));
        }
        return builder.build();
      } catch (IllegalArgumentException e) {
        throw new OptionsParsingException(
            String.format("invalid SerializedAndroidData: %s", e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "a list of preparsed android data in the format "
          + SerializedAndroidData.EXPECTED_FORMAT
          + "[&...]";
    }
  }

  /** Converter for a single {@link DependencySymbolFileProvider}. */
  public static class DependencySymbolFileProviderConverter
      implements Converter<DependencySymbolFileProvider> {

    @Override
    public DependencySymbolFileProvider convert(String input) throws OptionsParsingException {
      try {
        return DependencySymbolFileProvider.valueOf(input);
      } catch (IllegalArgumentException e) {
        throw new OptionsParsingException(
            String.format("invalid DependencyAndroidData: %s", e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return String.format(
          "a dependency android data in the format: %s[%s]",
          DependencySymbolFileProvider.commandlineFormat("1"),
          DependencySymbolFileProvider.commandlineFormat("2"));
    }
  }

  /**
   * Converter for {@link Revision}. Relies on {@code Revision#parseRevision(String)} to perform
   * conversion and validation.
   */
  public static class RevisionConverter implements Converter<Revision> {

    @Override
    public Revision convert(String input) throws OptionsParsingException {
      try {
        return Revision.parseRevision(input);
      } catch (NumberFormatException e) {
        throw new OptionsParsingException(e.getMessage());
      }
    }

    @Override
    public String getTypeDescription() {
      return "a revision number";
    }
  }

  /** Validating converter for Paths. A Path is considered valid if it resolves to a file. */
  public static class PathConverter implements Converter<Path> {

    private final boolean mustExist;

    public PathConverter() {
      this.mustExist = false;
    }

    protected PathConverter(boolean mustExist) {
      this.mustExist = mustExist;
    }

    @Override
    public Path convert(String input) throws OptionsParsingException {
      try {
        Path path = FileSystems.getDefault().getPath(input);
        if (mustExist && !Files.exists(path)) {
          throw new OptionsParsingException(
              String.format("%s is not a valid path: it does not exist.", input));
        }
        return path;
      } catch (InvalidPathException e) {
        throw new OptionsParsingException(
            String.format("%s is not a valid path: %s.", input, e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "a valid filesystem path";
    }
  }

  /**
   * Validating converter for Paths. A Path is considered valid if it resolves to a file and exists.
   */
  public static class ExistingPathConverter extends PathConverter {
    public ExistingPathConverter() {
      super(true);
    }
  }

  /** Converter for {@link VariantType}. */
  public static class VariantTypeConverter extends EnumConverter<VariantType> {
    public VariantTypeConverter() {
      super(VariantType.class, "variant type");
    }
  }

  /** Converter for {@link ManifestMerger2}.{@link MergeType}. */
  public static class MergeTypeConverter extends EnumConverter<MergeType> {
    public MergeTypeConverter() {
      super(MergeType.class, "merge type");
    }
  }

  /**
   * Validating converter for a list of Paths. A Path is considered valid if it resolves to a file.
   */
  @Deprecated
  public static class PathListConverter implements Converter<List<Path>> {

    private final PathConverter baseConverter;

    public PathListConverter() {
      this(false);
    }

    protected PathListConverter(boolean mustExist) {
      baseConverter = new PathConverter(mustExist);
    }

    @Override
    public List<Path> convert(String input) throws OptionsParsingException {
      List<Path> list = new ArrayList<>();
      for (String piece : input.split(":")) {
        if (!piece.isEmpty()) {
          list.add(baseConverter.convert(piece));
        }
      }
      return Collections.unmodifiableList(list);
    }

    @Override
    public String getTypeDescription() {
      return "a colon-separated list of paths";
    }
  }

  // Commas that are not escaped by a backslash.
  private static final String UNESCAPED_COMMA_REGEX = "(?<!\\\\)\\,";
  // Colons that are not escaped by a backslash.
  private static final String UNESCAPED_COLON_REGEX = "(?<!\\\\)\\:";

  private static String unescapeInput(String input) {
    return input.replace("\\:", ":").replace("\\,", ",");
  }

  /**
   * A converter for dictionary arguments of the format key:value[,key:value]*. The keys and values
   * may contain colons and commas as long as they are escaped with a backslash.
   */
  private abstract static class DictionaryConverter<K, V> implements Converter<Map<K, V>> {
    private final Converter<K> keyConverter;
    private final Converter<V> valueConverter;

    public DictionaryConverter(Converter<K> keyConverter, Converter<V> valueConverter) {
      this.keyConverter = keyConverter;
      this.valueConverter = valueConverter;
    }

    @Override
    public Map<K, V> convert(String input) throws OptionsParsingException {
      if (input.isEmpty()) {
        return ImmutableMap.of();
      }
      Map<K, V> map = new LinkedHashMap<>();
      // Only split on comma and colon that are not escaped with a backslash
      for (String entry : input.split(UNESCAPED_COMMA_REGEX)) {
        String[] entryFields = entry.split(UNESCAPED_COLON_REGEX, -1);
        if (entryFields.length < 2) {
          throw new OptionsParsingException(
              String.format(
                  "Dictionary entry [%s] does not contain both a key and a value.", entry));
        } else if (entryFields.length > 2) {
          throw new OptionsParsingException(
              String.format("Dictionary entry [%s] contains too many fields.", entry));
        }
        // Unescape any comma or colon that is not a key or value separator.
        String keyString = unescapeInput(entryFields[0]);
        K key = keyConverter.convert(keyString);
        if (map.containsKey(key)) {
          throw new OptionsParsingException(
              String.format("Dictionary already contains the key [%s].", keyString));
        }
        // Unescape any comma or colon that is not a key or value separator.
        String valueString = unescapeInput(entryFields[1]);
        V value = valueConverter.convert(valueString);
        map.put(key, value);
      }
      return ImmutableMap.copyOf(map);
    }

    @Override
    public String getTypeDescription() {
      // Retrieve types of dictionary through reflection to avoid overriding this method in each
      // subclass or passing types to this superclass.
      return String.format(
          "a comma-separated list of colon-separated key value pairs of the types %s and %s",
          ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0],
          ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1]);
    }
  }

  /**
   * A converter for dictionary arguments of the format key:value[,key:value]*. The keys and values
   * may contain colons and commas as long as they are escaped with a backslash. The key and value
   * types are both String.
   */
  public static class StringDictionaryConverter extends DictionaryConverter<String, String> {
    public StringDictionaryConverter() {
      super(IDENTITY_CONVERTER, IDENTITY_CONVERTER);
    }
    // The way {@link OptionsData} checks for generic types requires convert to have literal type
    // parameters and not argument type parameters.
    @Override
    public Map<String, String> convert(String input) throws OptionsParsingException {
      return super.convert(input);
    }
  }

  /**
   * A converter for dictionary arguments of the format key:value[,key:value]*. The keys and values
   * may contain colons and commas as long as they are escaped with a backslash. The key type is
   * Path and the value type is String.
   */
  public static class ExistingPathStringDictionaryConverter
      extends DictionaryConverter<Path, String> {
    public ExistingPathStringDictionaryConverter() {
      super(new ExistingPathConverter(), IDENTITY_CONVERTER);
    }
    // The way {@link OptionsData} checks for generic types requires convert to have literal type
    // parameters and not argument type parameters.
    @Override
    public Map<Path, String> convert(String input) throws OptionsParsingException {
      return super.convert(input);
    }
  }

  /** Converts a list of static library strings into paths. */
  @Deprecated
  public static class StaticLibraryListConverter implements Converter<List<StaticLibrary>> {
    static final Splitter SPLITTER = Splitter.on(File.pathSeparatorChar);

    static final StaticLibraryConverter libraryConverter = new StaticLibraryConverter();

    @Override
    public List<StaticLibrary> convert(String input) throws OptionsParsingException {
      final ImmutableList.Builder<StaticLibrary> builder = ImmutableList.<StaticLibrary>builder();
      for (String path : SPLITTER.splitToList(input)) {
        builder.add(libraryConverter.convert(path));
      }
      return builder.build();
    }

    @Override
    public String getTypeDescription() {
      return "Static resource libraries.";
    }
  }

  /** Converts a static library string into path. */
  public static class StaticLibraryConverter implements Converter<StaticLibrary> {

    static final PathConverter pathConverter = new PathConverter(true);

    @Override
    public StaticLibrary convert(String input) throws OptionsParsingException {
      return StaticLibrary.from(pathConverter.convert(input));
    }

    @Override
    public String getTypeDescription() {
      return "Static resource library.";
    }
  }

  /** Converts a string of resources and manifest into paths. */
  public static class CompiledResourcesConverter implements Converter<CompiledResources> {
    static final PathConverter pathConverter = new PathConverter(true);
    static final Pattern COMPILED_RESOURCE_FORMAT = Pattern.compile("(.+):(.+)");

    @Override
    public CompiledResources convert(String input) throws OptionsParsingException {
      final Matcher matched = COMPILED_RESOURCE_FORMAT.matcher(input);
      if (!matched.find()) {
        throw new OptionsParsingException("Expected format <resources zip>:<manifest>");
      }
      Path resources = pathConverter.convert(matched.group(1));
      Path manifest = pathConverter.convert(matched.group(2));
      return CompiledResources.from(resources, manifest);
    }

    @Override
    public String getTypeDescription() {
      return "Compiled resources zip.";
    }
  }
}
