// 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 com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
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.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.DiscardedChecker;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.MainDexClasses;
import com.android.tools.r8.shaking.MainDexListBuilder;
import com.android.tools.r8.shaking.RootSetBuilder;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
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.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

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

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

  private List<String> run(AndroidApp app, ExecutorService executor)
      throws IOException {
    try {
      DexApplication application =
          new ApplicationReader(app, options, timing).read(executor).toDirect();
      AppView<? extends AppInfoWithSubtyping> appView =
          AppView.createForR8(new AppInfoWithSubtyping(application), options);
      appView.setAppServices(AppServices.builder(appView).build());

      RootSet mainDexRootSet =
          new RootSetBuilder(appView, application, options.mainDexKeepRules).run(executor);

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

      Enqueuer enqueuer = new Enqueuer(appView, options, graphConsumer);
      Set<DexType> liveTypes = enqueuer.traceMainDex(mainDexRootSet, executor, timing);
      // LiveTypes is the result.
      MainDexClasses mainDexClasses = new MainDexListBuilder(liveTypes, application).run();

      List<String> result =
          mainDexClasses.getClasses().stream()
              .map(c -> c.toSourceString().replace('.', '/') + ".class")
              .sorted()
              .collect(Collectors.toList());

      if (options.mainDexListConsumer != null) {
        options.mainDexListConsumer.accept(String.join("\n", result), options.reporter);
      }

      if (!mainDexRootSet.checkDiscarded.isEmpty()) {
        new DiscardedChecker(mainDexRootSet, mainDexClasses.getClasses(), appView).run();
      }
      // Print -whyareyoukeeping results if any.
      if (whyAreYouKeepingConsumer != null) {
        for (DexReference reference : mainDexRootSet.reasonAsked) {
          whyAreYouKeepingConsumer.printWhyAreYouKeeping(
              enqueuer.getGraphNode(reference), System.out);
        }
      }

      return result;
    } catch (ExecutionException e) {
      throw R8.unwrapExecutionException(e);
    }
  }

  /**
   * 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.
   *
   * 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.
   * @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();
    ResultBox result = new ResultBox();

    ExceptionUtils.withMainDexListHandler(
        command.getReporter(),
        () -> {
          try {
            result.content = new GenerateMainDexList(options).run(app, executor);
          } finally {
            executor.shutdown();
          }
        });
    return result.content;
  }

  private static class ResultBox {
    List<String> content;
  }

  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);
    }
  }
}
