// Copyright (c) 2018, 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.ParseFlagInfoImpl.flag1;

import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.profile.art.ArtProfileConsumerUtils;
import com.android.tools.r8.profile.art.ArtProfileProviderUtils;
import com.android.tools.r8.profile.startup.StartupProfileProviderUtils;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Set;

public class D8CommandParser extends BaseCompilerCommandParser<D8Command, D8Command.Builder> {

  private static final Set<String> OPTIONS_WITH_ONE_PARAMETER =
      ImmutableSet.of(
          "--output",
          "--lib",
          "--classpath",
          "--pg-map",
          "--pg-map-output",
          "--partition-map-output",
          MIN_API_FLAG,
          "--main-dex-rules",
          "--main-dex-list",
          "--main-dex-list-output",
          "--desugared-lib",
          "--desugared-lib-pg-conf-output",
          THREAD_COUNT_FLAG,
          ART_PROFILE_FLAG,
          STARTUP_PROFILE_FLAG);

  // Note: this must be a subset of OPTIONS_WITH_ONE_PARAMETER.
  private static final Set<String> OPTIONS_WITH_TWO_PARAMETERS = ImmutableSet.of(ART_PROFILE_FLAG);

  public static List<ParseFlagInfo> getFlags() {
    return ImmutableList.<ParseFlagInfo>builder()
        .add(ParseFlagInfoImpl.getDebug(true))
        .add(ParseFlagInfoImpl.getRelease(false))
        .add(ParseFlagInfoImpl.getOutput())
        .add(ParseFlagInfoImpl.getLib())
        .add(ParseFlagInfoImpl.getClasspath())
        .add(ParseFlagInfoImpl.getMinApi())
        .add(
            ParseFlagInfoImpl.flag1(
                "--pg-map", "<file>", "Use <file> as a mapping file for distribution."))
        // TODO(b/183125319): Add help info once supported.
        // "  --pg-map-output <file>  # Enable line optimization and output mapping to <file>.",
        // "  --partition-map-output <file>  # Enable line optimization and output mapping to
        //   <file>.",
        .add(
            ParseFlagInfoImpl.flag0(
                "--intermediate", "Compile an intermediate result intended for later", "merging."))
        .add(
            ParseFlagInfoImpl.flag0(
                "--file-per-class",
                "Produce a separate dex file per class.",
                "Synthetic classes are in their own file."))
        .add(
            ParseFlagInfoImpl.flag0(
                "--file-per-class-file",
                "Produce a separate dex file per input .class file.",
                "Synthetic classes are with their originating class."))
        .add(ParseFlagInfoImpl.flag0("--no-desugaring", "Force disable desugaring."))
        .add(ParseFlagInfoImpl.getDesugaredLib())
        .add(
            flag1(
                "--desugared-lib-pg-conf-output",
                "<file>",
                "Output the Proguard configuration for L8 to <file>."))
        .add(ParseFlagInfoImpl.getMainDexRules())
        .add(ParseFlagInfoImpl.getMainDexList())
        .add(ParseFlagInfoImpl.getMainDexListOutput())
        .addAll(ParseFlagInfoImpl.getAssertionsFlags())
        .add(ParseFlagInfoImpl.getThreadCount())
        .add(ParseFlagInfoImpl.getMapDiagnostics())
        .add(ParseFlagInfoImpl.getAndroidPlatformBuild())
        .add(ParseFlagInfoImpl.getArtProfile())
        .add(ParseFlagInfoImpl.getStartupProfile())
        .add(ParseFlagInfoImpl.getVersion("d8"))
        .add(ParseFlagInfoImpl.getHelp())
        .build();
  }

  private static final String APK_EXTENSION = ".apk";
  private static final String JAR_EXTENSION = ".jar";
  private static final String ZIP_EXTENSION = ".zip";

  private static boolean isArchive(Path path) {
    String name = path.getFileName().toString().toLowerCase();
    return name.endsWith(APK_EXTENSION)
        || name.endsWith(JAR_EXTENSION)
        || name.endsWith(ZIP_EXTENSION);
  }

  static class OrderedClassFileResourceProvider implements ClassFileResourceProvider {
    static class Builder {
      private final ImmutableList.Builder<ClassFileResourceProvider> builder =
          ImmutableList.builder();
      boolean empty = true;

      OrderedClassFileResourceProvider build() {
        return new OrderedClassFileResourceProvider(builder.build());
      }

      Builder addClassFileResourceProvider(ClassFileResourceProvider provider) {
        builder.add(provider);
        empty = false;
        return this;
      }

      boolean isEmpty() {
        return empty;
      }
    }

    final List<ClassFileResourceProvider> providers;
    final Set<String> descriptors = Sets.newHashSet();

    private OrderedClassFileResourceProvider(ImmutableList<ClassFileResourceProvider> providers) {
      this.providers = providers;
      // Collect all descriptors that can be provided.
      this.providers.forEach(provider -> this.descriptors.addAll(provider.getClassDescriptors()));
    }

    static Builder builder() {
      return new Builder();
    }

    @Override
    public Set<String> getClassDescriptors() {
      return descriptors;
    }

    @Override
    public ProgramResource getProgramResource(String descriptor) {
      // Search the providers in order. Return the program resource from the first provider that
      // can provide it.
      for (ClassFileResourceProvider provider : providers) {
        if (provider.getClassDescriptors().contains(descriptor)) {
          return provider.getProgramResource(descriptor);
        }
      }
      return null;
    }
  }

  public static void main(String[] args) throws CompilationFailedException {
    D8Command command = parse(args, Origin.root()).build();
    if (command.isPrintHelp()) {
      System.out.println(getUsageMessage());
    } else {
      D8.run(command);
    }
  }

  static String getUsageMessage() {
    StringBuilder builder = new StringBuilder();
    StringUtils.appendLines(
        builder,
        "Usage: d8 [options] [@<argfile>] <input-files>",
        " where <input-files> are any combination of dex, class, zip, jar, or apk files",
        " and each <argfile> is a file containing additional arguments (one per line)",
        " and options are:");
    new ParseFlagPrinter().addFlags(ImmutableList.copyOf(getFlags())).appendLinesToBuilder(builder);
    return builder.toString();
  }

  /**
   * Parse the D8 command-line.
   *
   * <p>Parsing will set the supplied options or their default value if they have any.
   *
   * @param args Command-line arguments array.
   * @param origin Origin description of the command-line arguments.
   * @return D8 command builder with state set up according to parsed command line.
   */
  public static D8Command.Builder parse(String[] args, Origin origin) {
    return new D8CommandParser().parse(args, origin, D8Command.builder());
  }

  /**
   * Parse the D8 command-line.
   *
   * <p>Parsing will set the supplied options or their default value if they have any.
   *
   * @param args Command-line arguments array.
   * @param origin Origin description of the command-line arguments.
   * @param handler Custom defined diagnostics handler.
   * @return D8 command builder with state set up according to parsed command line.
   */
  public static D8Command.Builder parse(String[] args, Origin origin, DiagnosticsHandler handler) {
    return new D8CommandParser().parse(args, origin, D8Command.builder(handler));
  }

  private D8Command.Builder parse(String[] args, Origin origin, D8Command.Builder builder) {
    CompilationMode compilationMode = null;
    Path outputPath = null;
    OutputMode outputMode = null;
    boolean hasDefinedApiLevel = false;
    OrderedClassFileResourceProvider.Builder classpathBuilder =
        OrderedClassFileResourceProvider.builder();
    String[] expandedArgs = FlagFile.expandFlagFiles(args, builder::error);
    for (int i = 0; i < expandedArgs.length; i++) {
      String arg = expandedArgs[i].trim();
      String nextArg = null;
      String nextNextArg = null;
      if (OPTIONS_WITH_ONE_PARAMETER.contains(arg)) {
        if (++i < expandedArgs.length) {
          nextArg = expandedArgs[i];
        } else {
          builder.error(
              new StringDiagnostic("Missing parameter for " + expandedArgs[i - 1] + ".", origin));
          break;
        }
        if (OPTIONS_WITH_TWO_PARAMETERS.contains(arg)) {
          if (++i < expandedArgs.length) {
            nextNextArg = expandedArgs[i];
          } else {
            builder.error(
                new StringDiagnostic("Missing parameter for " + expandedArgs[i - 2] + ".", origin));
            break;
          }
        }
      }
      if (arg.length() == 0) {
        continue;
      } else if (arg.equals("--help")) {
        builder.setPrintHelp(true);
      } else if (arg.equals("--version")) {
        builder.setPrintVersion(true);
      } else if (arg.equals("--debug")) {
        if (compilationMode == CompilationMode.RELEASE) {
          builder.error(
              new StringDiagnostic("Cannot compile in both --debug and --release mode.", origin));
          continue;
        }
        compilationMode = CompilationMode.DEBUG;
      } else if (arg.equals("--release")) {
        if (compilationMode == CompilationMode.DEBUG) {
          builder.error(
              new StringDiagnostic("Cannot compile in both --debug and --release mode.", origin));
          continue;
        }
        compilationMode = CompilationMode.RELEASE;
      } else if (arg.equals("--file-per-class")) {
        outputMode = OutputMode.DexFilePerClass;
      } else if (arg.equals("--file-per-class-file")) {
        outputMode = OutputMode.DexFilePerClassFile;
      } else if (arg.equals("--classfile")) {
        outputMode = OutputMode.ClassFile;
      } else if (arg.equals("--pg-map")) {
        builder.setProguardInputMapFile(Paths.get(nextArg));
      } else if (arg.equals("--pg-map-output")) {
        builder.setProguardMapOutputPath(Paths.get(nextArg));
      } else if (arg.equals("--partition-map-output")) {
        builder.setPartitionMapOutputPath(Paths.get(nextArg));
      } else if (arg.equals("--output")) {
        if (outputPath != null) {
          builder.error(
              new StringDiagnostic(
                  "Cannot output both to '" + outputPath.toString() + "' and '" + nextArg + "'",
                  origin));
          continue;
        }
        outputPath = Paths.get(nextArg);
      } else if (arg.equals("--lib")) {
        addLibraryArgument(builder, origin, nextArg);
      } else if (arg.equals("--classpath")) {
        Path file = Paths.get(nextArg);
        try {
          if (!Files.exists(file)) {
            throw new NoSuchFileException(file.toString());
          }
          if (isArchive(file)) {
            classpathBuilder.addClassFileResourceProvider(new ArchiveClassFileProvider(file));
          } else if (Files.isDirectory(file)) {
            classpathBuilder.addClassFileResourceProvider(
                DirectoryClassFileProvider.fromDirectory(file));
          } else {
            builder.error(
                new StringDiagnostic("Unsupported classpath file type", new PathOrigin(file)));
          }
        } catch (IOException e) {
          builder.error(new ExceptionDiagnostic(e, new PathOrigin(file)));
        }
      } else if (arg.equals("--main-dex-rules")) {
        builder.addMainDexRulesFiles(Paths.get(nextArg));
      } else if (arg.equals("--main-dex-list")) {
        builder.addMainDexListFiles(Paths.get(nextArg));
      } else if (arg.equals("--main-dex-list-output")) {
        builder.setMainDexListOutputPath(Paths.get(nextArg));
      } else if (arg.equals("--optimize-multidex-for-linearalloc")) {
        builder.setOptimizeMultidexForLinearAlloc(true);
      } else if (arg.equals(MIN_API_FLAG)) {
        if (hasDefinedApiLevel) {
          builder.error(
              new StringDiagnostic("Cannot set multiple " + MIN_API_FLAG + " options", origin));
        } else {
          parsePositiveIntArgument(
              builder::error, MIN_API_FLAG, nextArg, origin, builder::setMinApiLevel);
          hasDefinedApiLevel = true;
        }
      } else if (arg.equals(THREAD_COUNT_FLAG)) {
        parsePositiveIntArgument(
            builder::error, THREAD_COUNT_FLAG, nextArg, origin, builder::setThreadCount);
      } else if (arg.equals("--intermediate")) {
        builder.setIntermediate(true);
      } else if (arg.equals("--no-desugaring")) {
        builder.setDisableDesugaring(true);
      } else if (arg.equals("--desugared-lib")) {
        builder.addDesugaredLibraryConfiguration(StringResource.fromFile(Paths.get(nextArg)));
      } else if (arg.equals("--desugared-lib-pg-conf-output")) {
        StringConsumer consumer = new StringConsumer.FileConsumer(Paths.get(nextArg));
        builder.setDesugaredLibraryKeepRuleConsumer(consumer);
      } else if (arg.equals("--android-platform-build")) {
        builder.setAndroidPlatformBuild(true);
      } else if (arg.equals(ART_PROFILE_FLAG)) {
        Path artProfilePath = Paths.get(nextArg);
        Path rewrittenArtProfilePath = Paths.get(nextNextArg);
        builder.addArtProfileForRewriting(
            ArtProfileProviderUtils.createFromHumanReadableArtProfile(artProfilePath),
            ArtProfileConsumerUtils.create(rewrittenArtProfilePath));
      } else if (arg.equals(STARTUP_PROFILE_FLAG)) {
        Path startupProfilePath = Paths.get(nextArg);
        builder.addStartupProfileProviders(
            StartupProfileProviderUtils.createFromHumanReadableArtProfile(startupProfilePath));
      } else if (arg.startsWith("--")) {
        if (tryParseAssertionArgument(builder, arg, origin)) {
          continue;
        }
        int argsConsumed = tryParseMapDiagnostics(builder, arg, expandedArgs, i, origin);
        if (argsConsumed >= 0) {
          i += argsConsumed;
          continue;
        }
        argsConsumed = tryParseDump(builder, arg, expandedArgs, i, origin);
        if (argsConsumed >= 0) {
          i += argsConsumed;
          continue;
        }
        builder.error(new StringDiagnostic("Unknown option: " + arg, origin));
      } else if (arg.startsWith("@")) {
        builder.error(new StringDiagnostic("Recursive @argfiles are not supported: ", origin));
      } else {
        builder.addProgramFiles(Paths.get(arg));
      }
    }
    if (!classpathBuilder.isEmpty()) {
      builder.addClasspathResourceProvider(classpathBuilder.build());
    }
    if (compilationMode != null) {
      builder.setMode(compilationMode);
    }
    if (outputMode == null) {
      outputMode = OutputMode.DexIndexed;
    }
    if (outputPath == null) {
      outputPath = Paths.get(".");
    }
    return builder.setOutput(outputPath, outputMode);
  }
}
