// Copyright (c) 2017, 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.utils.ExceptionUtils.unwrapExecutionException;

import com.android.tools.r8.StringConsumer.ForwardingConsumer;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.MainDexInfo;
import com.android.tools.r8.shaking.MainDexListBuilder;
import com.android.tools.r8.shaking.RootSetUtils.MainDexRootSet;
import com.android.tools.r8.shaking.WhyAreYouKeepingConsumer;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.SortingStringConsumer;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

@Keep
public class GenerateMainDexList {
  private final Timing timing = new Timing("maindex");
  private final InternalOptions options;

  public GenerateMainDexList(InternalOptions options) {
    this.options = options;
  }

  private void run(AndroidApp app, ExecutorService executor, SortingStringConsumer consumer)
      throws IOException {
    try {
      DexApplication application = new ApplicationReader(app, options, timing).read(executor);
      traceMainDex(executor, application, MainDexInfo.none())
          .forEach(type -> consumer.accept(type.toBinaryName() + ".class", options.reporter));
      consumer.finished(options.reporter);
    } catch (ExecutionException e) {
      throw unwrapExecutionException(e);
    }
  }

  public MainDexInfo traceMainDex(
      ExecutorService executor, DexApplication application, MainDexInfo existingMainDexInfo)
      throws ExecutionException {
    AppView<? extends AppInfoWithClassHierarchy> appView =
        AppView.createForR8(application.toDirect(), existingMainDexInfo);
    appView.setAppServices(AppServices.builder(appView).build());

    MainDexListBuilder.checkForAssumedLibraryTypes(appView.appInfo());

    SubtypingInfo subtypingInfo = new SubtypingInfo(appView);

    MainDexRootSet mainDexRootSet =
        MainDexRootSet.builder(appView, subtypingInfo, options.mainDexKeepRules).build(executor);
    appView.setMainDexRootSet(mainDexRootSet);

    GraphConsumer graphConsumer = options.mainDexKeptGraphConsumer;
    WhyAreYouKeepingConsumer whyAreYouKeepingConsumer = null;
    if (!mainDexRootSet.reasonAsked.isEmpty()) {
      whyAreYouKeepingConsumer = new WhyAreYouKeepingConsumer(graphConsumer);
      graphConsumer = whyAreYouKeepingConsumer;
    }

    Enqueuer enqueuer =
        EnqueuerFactory.createForGenerateMainDexList(
            appView, executor, subtypingInfo, graphConsumer);
    MainDexInfo mainDexInfo = enqueuer.traceMainDex(executor, timing);
    R8.processWhyAreYouKeepingAndCheckDiscarded(
        mainDexRootSet,
        () -> {
          ArrayList<DexProgramClass> classes = new ArrayList<>();
          // TODO(b/131668850): This is not a deterministic order!
          mainDexInfo.forEach(
              type -> {
                DexClass clazz = appView.definitionFor(type);
                assert clazz.isProgramClass();
                classes.add(clazz.asProgramClass());
              });
          return classes;
        },
        whyAreYouKeepingConsumer,
        appView,
        enqueuer,
        true,
        options,
        timing,
        executor);

    return mainDexInfo;
  }

  /**
   * Main API entry for computing the main-dex list.
   *
   * The main-dex list is represented as a list of strings, each string specifies one class to
   * keep in the primary dex file (<code>classes.dex</code>).
   *
   * A class is specified using the following format: "com/example/MyClass.class". That is
   * "/" as separator between package components, and a trailing ".class".
   *
   * @param command main dex-list generator command.
   * @return classes to keep in the primary dex file.
   */
  public static List<String> run(GenerateMainDexListCommand command)
      throws CompilationFailedException {
    ExecutorService executorService = ThreadUtils.getExecutorService(command.getInternalOptions());
    try {
      return run(command, executorService);
    } finally {
      executorService.shutdown();
    }
  }

  /**
   * Main API entry for computing the main-dex list.
   *
   * <p>The main-dex list is represented as a list of strings, each string specifies one class to
   * keep in the primary dex file (<code>classes.dex</code>).
   *
   * <p>A class is specified using the following format: "com/example/MyClass.class". That is "/" as
   * separator between package components, and a trailing ".class".
   *
   * @param command main dex-list generator command.
   * @param executor executor service from which to get threads for multi-threaded processing.
   * @return classes to keep in the primary dex file.
   */
  public static List<String> run(GenerateMainDexListCommand command, ExecutorService executor)
      throws CompilationFailedException {
    AndroidApp app = command.getInputApp();
    InternalOptions options = command.getInternalOptions();
    List<String> result = new ArrayList<>();
    ExceptionUtils.withMainDexListHandler(
        command.getReporter(),
        () -> {
          try {
            new GenerateMainDexList(options)
                .run(
                    app,
                    executor,
                    new SortingStringConsumer(
                        new ForwardingConsumer(options.mainDexListConsumer) {
                          @Override
                          public void accept(String string, DiagnosticsHandler handler) {
                            result.add(string);
                            super.accept(string, handler);
                          }
                        }));
          } finally {
            executor.shutdown();
          }
        });
    return result;
  }

  public static void main(String[] args) throws CompilationFailedException {
    GenerateMainDexListCommand.Builder builder = GenerateMainDexListCommand.parse(args);
    GenerateMainDexListCommand command = builder.build();
    if (command.isPrintHelp()) {
      System.out.println(GenerateMainDexListCommand.USAGE_MESSAGE);
      return;
    }
    if (command.isPrintVersion()) {
      System.out.println("MainDexListGenerator " + Version.LABEL);
      return;
    }
    List<String> result = run(command);
    if (command.getMainDexListConsumer() == null) {
      result.forEach(System.out::println);
    }
  }
}
