// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;

import static com.android.tools.r8.BaseCompilerCommandParser.ART_PROFILE_FLAG;
import static com.android.tools.r8.BaseCompilerCommandParser.LIB_FLAG;
import static com.android.tools.r8.BaseCompilerCommandParser.MAP_DIAGNOSTICS;
import static com.android.tools.r8.BaseCompilerCommandParser.MIN_API_FLAG;
import static com.android.tools.r8.BaseCompilerCommandParser.THREAD_COUNT_FLAG;
import static com.android.tools.r8.BaseCompilerCommandParser.VERBOSE_SYNTHETIC_NAMES;
import static com.android.tools.r8.D8CommandParser.STARTUP_PROFILE_FLAG;
import static com.android.tools.r8.R8CommandParser.ISOLATED_SPLITS_FLAG;

import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ParseFlagInfoImpl implements ParseFlagInfo {

  private static String defaultSuffix(boolean isDefault) {
    return isDefault ? " (default)" : "";
  }

  public static ParseFlagInfoImpl getRelease(boolean isDefault) {
    return flag0(
        "--release", "Compile without debugging information" + defaultSuffix(isDefault) + ".");
  }

  public static ParseFlagInfoImpl getDebug(boolean isDefault) {
    return flag0("--debug", "Compile with debugging information" + defaultSuffix(isDefault) + ".");
  }

  public static ParseFlagInfoImpl getDex(boolean isDefault) {
    return flag0("--dex", "Compile program to DEX file format" + defaultSuffix(isDefault) + ".");
  }

  public static ParseFlagInfoImpl getClassfile() {
    return flag0("--classfile", "Compile program to Java classfile format.");
  }

  public static ParseFlagInfoImpl getOutput() {
    return flag1(
        "--output",
        "<file>",
        "Output result in <file>.",
        "<file> must be an existing directory or a zip file.");
  }

  public static ParseFlagInfoImpl getGlobals() {
    return flag1(
        "--globals",
        "<file>",
        "Global synthetics <file> from a previous intermediate compilation.",
        "The <file> may be either a zip-archive of global synthetics or the",
        "global-synthetic files directly.");
  }

  public static ParseFlagInfoImpl getGlobalsOutput() {
    return flag1(
        "--globals-output",
        "<file>",
        "Output global synthetics in <file>.",
        "<file> must be an existing directory or a non-existent zip archive.");
  }

  public static ParseFlagInfoImpl getLib() {
    return flag1(LIB_FLAG, "<file|jdk-home>", "Add <file|jdk-home> as a library resource.");
  }

  public static ParseFlagInfoImpl getClasspath() {
    return flag1("--classpath", "<file>", "Add <file> as a classpath resource.");
  }

  public static ParseFlagInfoImpl getMinApi() {
    return flag1(
        MIN_API_FLAG,
        "<number>",
        "Minimum Android API level compatibility (default: "
            + AndroidApiLevel.getDefault().getLevel()
            + ").");
  }

  public static ParseFlagInfoImpl getDesugaredLib() {
    return flag1(
        "--desugared-lib",
        "<file>",
        "Specify desugared library configuration.",
        "<file> is a desugared library configuration (json).");
  }

  public static ParseFlagInfoImpl getMainDexRules() {
    return flag1(
        "--main-dex-rules",
        "<file>",
        "Proguard keep rules for classes to place in the",
        "primary dex file.");
  }

  public static ParseFlagInfoImpl getMainDexList() {
    return flag1("--main-dex-list", "<file>", "List of classes to place in the primary dex file.");
  }

  public static ParseFlagInfoImpl getMainDexListOutput() {
    return flag1("--main-dex-list-output", "<file>", "Output resulting main dex list in <file>.");
  }

  public static ParseFlagInfoImpl getVersion(String tool) {
    return flag0("--version", "Print the version of " + tool + ".");
  }

  public static ParseFlagInfoImpl getHelp() {
    return flag0("--help", "Print this message.");
  }

  public static ParseFlagInfoImpl getPgConf() {
    return ParseFlagInfoImpl.flag1("--pg-conf", "<file>", "Proguard configuration <file>.");
  }

  public static ParseFlagInfoImpl getPgMapOutput() {
    return ParseFlagInfoImpl.flag1(
        "--pg-map-output", "<file>", "Output the resulting name and line mapping to <file>.");
  }

  public static ParseFlagInfoImpl getPartitionMapOutput() {
    return ParseFlagInfoImpl.flag1(
        "--partition-map-output", "<file>", "Output the resulting mapping to <file>.");
  }

  public static List<ParseFlagInfoImpl> getAssertionsFlags() {
    return ImmutableList.of(
        flag0a1(
            "--force-enable-assertions[:[<class name>|<package name>...]]",
            "--force-ea[:[<class name>|<package name>...]]",
            "Forcefully enable javac generated assertion code."),
        flag0a1(
            "--force-disable-assertions[:[<class name>|<package name>...]]",
            "--force-da[:[<class name>|<package name>...]]",
            "Forcefully disable javac generated assertion code.",
            "This is the default handling of javac assertion code",
            "when generating DEX file format."),
        flag0a1(
            "--force-passthrough-assertions[:[<class name>|<package name>...]]",
            "--force-pa[:[<class name>|<package name>...]]",
            "Don't change javac generated assertion code. This",
            "is the default handling of javac assertion code when",
            "generating class file format."),
        flag0a1(
            "--force-assertions-handler:<handler method>[:[<class name>|<package name>...]]",
            "--force-ah:<handler method>[:[<class name>|<package name>...]]",
            "Change javac and kotlinc generated assertion code",
            "to invoke the method <handler method> with each",
            "assertion error instead of throwing it.",
            "The <handler method> is specified as a class name",
            "followed by a dot and the method name.",
            "The handler method must take a single argument of",
            "type java.lang.Throwable and have return type void."));
  }

  public static ParseFlagInfoImpl getThreadCount() {
    return flag1(
        THREAD_COUNT_FLAG,
        "<number>",
        "Use <number> of threads for compilation.",
        "If not specified the number will be based on",
        "heuristics taking the number of cores into account.");
  }

  public static ParseFlagInfoImpl getMapDiagnostics() {
    return flag2(
        MAP_DIAGNOSTICS + "[:<type>]",
        "<from-level>",
        "<to-level>",
        "Map diagnostics of <type> (default any) reported as",
        "<from-level> to <to-level> where <from-level> and",
        "<to-level> are one of 'info', 'warning', or 'error'",
        "and the optional <type> is either the simple or",
        "fully qualified Java type name of a diagnostic.",
        "If <type> is unspecified, all diagnostics at ",
        "<from-level> will be mapped.",
        "Note that fatal compiler errors cannot be mapped.");
  }

  public static ParseFlagInfoImpl getAndroidPlatformBuild() {
    return flag0(
        "--android-platform-build",
        "Compile as a platform build where the runtime/bootclasspath",
        "is assumed to be the version specified by --min-api.");
  }

  public static ParseFlagInfoImpl getArtProfile() {
    return flag2(
        ART_PROFILE_FLAG,
        "<input>",
        "<output>",
        "Rewrite human readable ART profile read from <input> and write to <output>.");
  }

  public static ParseFlagInfoImpl getStartupProfile() {
    return flag1(STARTUP_PROFILE_FLAG, "<file>", "Startup profile <file> to use for dex layout.");
  }

  public static ParseFlagInfoImpl getVerboseSyntheticNames() {
    return flag0(
        VERBOSE_SYNTHETIC_NAMES,
        "Enable verbose synthetic names that use the `$$ExternalSynthetic` marker.");
  }

  public static ParseFlagInfoImpl getIsolatedSplits() {
    return flag0(
        ISOLATED_SPLITS_FLAG,
        "Specifies that the application is using isolated splits, i.e., if split APKs installed "
            + "for this application are loaded into their own Context objects.");
  }

  public static ParseFlagInfoImpl flag0(String flag, String... help) {
    return flag(flag, Collections.emptyList(), Arrays.asList(help));
  }

  public static ParseFlagInfoImpl flag1(String flag, String arg, String... help) {
    return flag(flag, Collections.singletonList(arg), Arrays.asList(help));
  }

  public static ParseFlagInfoImpl flag2(String flag, String arg1, String arg2, String... help) {
    return flag(flag, ImmutableList.of(arg1, arg2), Arrays.asList(help));
  }

  private static String fmt(String flag, List<String> args) {
    StringBuilder builder = new StringBuilder(flag);
    for (String arg : args) {
      builder.append(" ").append(arg);
    }
    return builder.toString();
  }

  @SuppressWarnings("UnusedVariable")
  public static ParseFlagInfoImpl flag(String flag, List<String> args, List<String> help) {
    return new ParseFlagInfoImpl(flag, fmt(flag, args), Collections.emptyList(), help);
  }

  public static ParseFlagInfoImpl flag0a1(String flag, String alternative, String... help) {
    return new ParseFlagInfoImpl(
        null, flag, Collections.singletonList(alternative), Arrays.asList(help));
  }

  // Note that the raw flag may be non-representable as in the case of the family of flags for
  // assertions.
  @SuppressWarnings("UnusedVariable")
  private final String rawFlag;

  private final String flagWithArgs;
  private final List<String> alternatives;
  private final List<String> flagHelp;

  public ParseFlagInfoImpl(
      String rawFlag, String flagWithArgs, List<String> alternatives, List<String> flagHelp) {
    // Raw flag may be null if it does not have a unique definition.
    assert flagWithArgs != null;
    assert alternatives != null;
    assert flagHelp != null;
    this.rawFlag = rawFlag;
    this.flagWithArgs = flagWithArgs;
    this.alternatives = alternatives;
    this.flagHelp = flagHelp;
  }

  @Override
  public String getFlagFormat() {
    return flagWithArgs;
  }

  @Override
  public List<String> getFlagFormatAlternatives() {
    return alternatives;
  }

  @Override
  public List<String> getFlagHelp() {
    return flagHelp;
  }
}
