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

import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DexSplitterHelper;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.utils.FeatureClassMapping;
import com.android.tools.r8.utils.FeatureClassMapping.FeatureMappingException;
import com.android.tools.r8.utils.OptionsParsing;
import com.android.tools.r8.utils.OptionsParsing.ParseContext;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class DexSplitter {

  private static final String DEFAULT_OUTPUT_ARCHIVE_FILENAME = "split";

  private static final boolean PRINT_ARGS = false;

  public static class Options {
    List<String> inputArchives = new ArrayList<>();
    List<String> featureJars = new ArrayList<>();
    String splitBaseName = DEFAULT_OUTPUT_ARCHIVE_FILENAME;
    String featureSplitMapping;
    String proguardMap;
  }

  private static Options parseArguments(String[] args) throws IOException {
    Options options = new Options();
    ParseContext context = new ParseContext(args);
    while (context.head() != null) {
      List<String> input = OptionsParsing.tryParseMulti(context, "--input");
      if (input != null) {
        options.inputArchives.addAll(input);
        continue;
      }
      List<String> featureJars = OptionsParsing.tryParseMulti(context, "--feature-jar");
      if (featureJars != null) {
        options.featureJars.addAll(featureJars);
        continue;
      }
      String output = OptionsParsing.tryParseSingle(context, "--output", "-o");
      if (output != null) {
        options.splitBaseName = output;
        continue;
      }
      String proguardMap = OptionsParsing.tryParseSingle(context, "--proguard-map", null);
      if (proguardMap != null) {
        options.proguardMap = proguardMap;
        continue;
      }
      String featureSplit = OptionsParsing.tryParseSingle(context, "--feature-splits", null);
      if (featureSplit != null) {
        options.featureSplitMapping = featureSplit;
        continue;
      }
      throw new RuntimeException(String.format("Unknown options: '%s'.", context.head()));
    }
    return options;
  }

  private static FeatureClassMapping createFeatureClassMapping(Options options)
      throws IOException, FeatureMappingException, ResourceException {
    if (options.featureSplitMapping != null) {
      return FeatureClassMapping.fromSpecification(Paths.get(options.featureSplitMapping));
    }
    assert !options.featureJars.isEmpty();
    return FeatureClassMapping.fromJarFiles(options.featureJars);
  }

  private static void run(String[] args)
      throws CompilationFailedException, IOException, CompilationException, ExecutionException,
          ResourceException, FeatureMappingException {
    Options options = parseArguments(args);
    run(options);
  }

  public static void run(Options options)
      throws IOException, FeatureMappingException, ResourceException, CompilationException,
      ExecutionException, CompilationFailedException {
    if (options.inputArchives.isEmpty()) {
      throw new RuntimeException("Need at least one --input");
    }
    if (options.featureSplitMapping == null && options.featureJars.isEmpty()) {
      throw new RuntimeException("You must supply a feature split mapping or feature jars");
    }
    if (options.featureSplitMapping != null && !options.featureJars.isEmpty()) {
      throw new RuntimeException("You can't supply both a feature split mapping and feature jars");
    }

    D8Command.Builder builder = D8Command.builder();
    for (String s : options.inputArchives) {
      builder.addProgramFiles(Paths.get(s));
    }
    // We set the actual consumer on the ApplicationWriter when we have calculated the distribution
    // since we don't yet know the distribution.
    builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());

    FeatureClassMapping featureClassMapping = createFeatureClassMapping(options);

    DexSplitterHelper.run(
        builder.build(), featureClassMapping, options.splitBaseName, options.proguardMap);
  }

  public static void main(String[] args) {
    try {
      if (PRINT_ARGS) {
        printArgs(args);
      }
      run(args);
    } catch (CompilationFailedException
        | IOException
        | CompilationException
        | ExecutionException
        | ResourceException
        | FeatureMappingException e) {
      System.err.println("Splitting failed: " + e.getMessage());
      System.exit(1);
    }
  }

  private static void printArgs(String[] args) {
    System.err.printf("r8.DexSplitter");
    for (String s : args) {
      System.err.printf(" %s", s);
    }
    System.err.println("");
  }
}
