// 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.AssertionUtils.forTesting;
import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;

import com.android.tools.r8.androidapi.ApiReferenceStubber;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.graph.AppInfo;
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.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.LazyLoadedDexApplication;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.analysis.ClassInitializerAssertionEnablingAnalysis;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger;
import com.android.tools.r8.inspector.internal.InspectorImpl;
import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
import com.android.tools.r8.ir.conversion.PrimaryD8L8IRConverter;
import com.android.tools.r8.ir.desugar.TypeRewriter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAmender;
import com.android.tools.r8.ir.optimize.AssertionsRewriter;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
import com.android.tools.r8.naming.RecordRewritingNamingLens;
import com.android.tools.r8.naming.VarHandleDesugaringRewritingNamingLens;
import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.profile.startup.instrumentation.StartupInstrumentation;
import com.android.tools.r8.shaking.AssumeInfoCollection;
import com.android.tools.r8.shaking.MainDexInfo;
import com.android.tools.r8.synthesis.SyntheticFinalization;
import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
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.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
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.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

/**
 * The D8 dex compiler.
 *
 * <p>D8 performs modular compilation to DEX bytecode. It supports compilation of Java bytecode and
 * Android DEX bytecode to DEX bytecode including merging a mix of these input formats.
 *
 * <p>The D8 dexer API is intentionally limited and should "do the right thing" given a command. If
 * this API does not suffice please contact the D8/R8 team.
 *
 * <p>The compiler is invoked by calling {@link #run(D8Command) D8.run} with an appropriate {@link
 * D8Command}. For example:
 *
 * <pre>
 *   D8.run(D8Command.builder()
 *       .addProgramFiles(inputPathA, inputPathB)
 *       .setOutput(outputPath, OutputMode.DexIndexed)
 *       .build());
 * </pre>
 *
 * The above reads the input files denoted by {@code inputPathA} and {@code inputPathB}, compiles
 * them to DEX bytecode (compiling from Java bytecode for such inputs and merging for DEX inputs),
 * and then writes the result to the directory or zip archive specified by {@code outputPath}.
 */
@KeepForApi
public final class D8 {

  private D8() {}

  /**
   * Main API entry for the D8 dexer.
   *
   * @param command D8 command.
   */
  public static void run(D8Command command) throws CompilationFailedException {
    AndroidApp app = command.getInputApp();
    InternalOptions options = command.getInternalOptions();
    ExecutorService executor = ThreadUtils.getExecutorService(options);
    ExceptionUtils.withD8CompilationHandler(
        command.getReporter(),
        () -> {
          try {
            runInternal(app, options, executor);
          } finally {
            executor.shutdown();
          }
        });
  }

  /**
   * Main API entry for the D8 dexer with a externally supplied executor service.
   *
   * @param command D8 command.
   * @param executor executor service from which to get threads for multi-threaded processing.
   */
  public static void run(D8Command command, ExecutorService executor)
      throws CompilationFailedException {
    AndroidApp app = command.getInputApp();
    InternalOptions options = command.getInternalOptions();
    ExceptionUtils.withD8CompilationHandler(
        command.getReporter(),
        () -> {
          runInternal(app, options, executor);
        });
  }

  private static void run(String[] args) throws CompilationFailedException {
    D8Command command = D8Command.parse(args, CommandLineOrigin.INSTANCE).build();
    if (command.isPrintHelp()) {
      System.out.println(D8CommandParser.getUsageMessage());
      return;
    }
    if (command.isPrintVersion()) {
      System.out.println("D8 " + Version.getVersionString());
      return;
    }
    InternalOptions options = command.getInternalOptions();
    AndroidApp app = command.getInputApp();
    runForTesting(app, options);
  }

  /**
   * Command-line entry to D8.
   *
   * <p>See {@link D8CommandParser#getUsageMessage()} or run {@code d8 --help} for usage
   * information.
   */
  public static void main(String[] args) {
    if (args.length == 0) {
      throw new RuntimeException(
          StringUtils.joinLines("Invalid invocation.", D8CommandParser.getUsageMessage()));
    }
    ExceptionUtils.withMainProgramHandler(() -> run(args));
  }

  static void runForTesting(AndroidApp inputApp, InternalOptions options)
      throws CompilationFailedException {
    ExecutorService executor = ThreadUtils.getExecutorService(options);
    ExceptionUtils.withD8CompilationHandler(
        options.reporter,
        () -> {
          try {
            runInternal(inputApp, options, executor);
          } finally {
            executor.shutdown();
          }
        });
  }

  private static AppView<AppInfo> readApp(
      AndroidApp inputApp, InternalOptions options, ExecutorService executor, Timing timing)
      throws IOException {
    timing.begin("Application read");
    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
    LazyLoadedDexApplication app = applicationReader.read(executor);
    timing.end();
    timing.begin("Load desugared lib");
    options.loadMachineDesugaredLibrarySpecification(timing, app);
    timing.end();
    TypeRewriter typeRewriter = options.getTypeRewriter();
    AppInfo appInfo =
        timing.time(
            "Create app-info",
            () ->
                AppInfo.createInitialAppInfo(
                    app,
                    options.isGeneratingDexIndexed()
                        ? GlobalSyntheticsStrategy.forSingleOutputMode()
                        : GlobalSyntheticsStrategy.forPerFileMode(),
                    applicationReader.readMainDexClasses(app)));
    return timing.time("Create app-view", () -> AppView.createForD8(appInfo, typeRewriter, timing));
  }

  static void runInternal(AndroidApp inputApp, InternalOptions options, ExecutorService executor)
      throws IOException {
    if (options.printMemory) {
      // Run GC twice to remove objects with finalizers.
      System.gc();
      System.gc();
      Runtime runtime = Runtime.getRuntime();
      System.out.println("D8 is running with total memory:" + runtime.totalMemory());
      System.out.println("D8 is running with free memory:" + runtime.freeMemory());
      System.out.println("D8 is running with max memory:" + runtime.maxMemory());
    }
    Timing timing = Timing.create("D8 " + Version.LABEL, options);
    try {
      timing.begin("Pre conversion");
      // Synthetic assertion to check that testing assertions works and can be enabled.
      assert forTesting(options, () -> !options.testing.testEnableTestAssertions);

      timing.begin("Read input app");
      AppView<AppInfo> appView = readApp(inputApp, options, executor, timing);
      timing.end();
      timing.begin("Initialize assume info collection");
      initializeAssumeInfoCollection(appView);
      timing.end();
      timing.begin("Desugared library amend");
      DesugaredLibraryAmender.run(appView);
      timing.end();
      timing.begin("Collect input synthetics");
      SyntheticItems.collectSyntheticInputs(appView);
      timing.end();

      if (AssertionsRewriter.isEnabled(options)) {
        // Run analysis to mark all <clinit> methods having the javac generated assertion
        // enabling code.
        ClassInitializerAssertionEnablingAnalysis analysis =
            new ClassInitializerAssertionEnablingAnalysis(
                appView, OptimizationFeedbackSimple.getInstance());
        ThreadUtils.processItems(
            appView.appInfo().classes(),
            clazz -> {
              ProgramMethod classInitializer = clazz.getProgramClassInitializer();
              if (classInitializer != null) {
                analysis.processNewlyLiveMethod(classInitializer, clazz, null, null);
              }
            },
            appView.options().getThreadingModule(),
            executor);
      }

      if (options.testing.enableD8ResourcesPassThrough) {
        appView.setAppServices(AppServices.builder(appView).build());
      }
      timing.end();
      new PrimaryD8L8IRConverter(appView, timing).convert(appView, executor);
      timing.begin("Post conversion");

      // Close any internal archive providers now the application is fully processed.
      inputApp.closeInternalArchiveProviders();

      // If a method filter is present don't produce output since the application is likely partial.
      if (options.hasMethodsFilter()) {
        System.out.println("Finished compilation with method filter: ");
        options.methodsFilter.forEach((m) -> System.out.println("  - " + m));
      }

      // Preserve markers from input dex code and add a marker with the current version
      // if there were class file inputs.
      boolean hasClassResources = appView.appInfo().app().getFlags().hasReadProgramClassFromCf();
      boolean hasDexResources = appView.appInfo().app().getFlags().hasReadProgramClassFromDex();

      Marker marker = hasClassResources ? options.getMarker() : null;

      timing.time(
          "Run inspections",
          () ->
              InspectorImpl.runInspections(options.outputInspections, appView.appInfo().classes()));

      timing.time(
          "Create prefix rewriting lens",
          () ->
              appView.setNamingLens(
                  PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView)));

      timing.time(
          "Create record rewriting lens",
          () ->
              appView.setNamingLens(
                  RecordRewritingNamingLens.createRecordRewritingNamingLens(appView)));

      if (options.isGeneratingDex()
          && hasDexResources
          && hasClassResources
          && appView.typeRewriter.isRewriting()) {
        // There are both cf and dex inputs in the program, and rewriting is required for
        // desugared library only on cf inputs. We cannot easily rewrite part of the program
        // without iterating again the IR. We fall-back to writing one app with rewriting and
        // merging it with the other app in rewriteNonDexInputs.
        timing.begin("Rewrite non-dex inputs");
        DexApplication app = rewriteNonDexInputs(appView, inputApp, executor, marker, timing);
        timing.end();
        appView.setAppInfo(
            new AppInfo(
                appView.appInfo().getSyntheticItems().commit(app),
                appView.appInfo().getMainDexInfo()));
        appView.setNamingLens(NamingLens.getIdentityLens());
      } else if (options.isGeneratingDex() && hasDexResources) {
        appView.setNamingLens(NamingLens.getIdentityLens());
      }

      // Since tracing is not lens aware, this needs to be done prior to synthetic finalization
      // which will construct a graph lens.
      if (options.isGeneratingDex() && !options.mainDexKeepRules.isEmpty()) {
        timing.begin("Generate main-dex list");
        appView.dexItemFactory().clearTypeElementsCache();
        MainDexInfo mainDexInfo =
            new GenerateMainDexList(options).traceMainDexForD8(appView, executor);
        appView.setAppInfo(appView.appInfo().rebuildWithMainDexInfo(mainDexInfo));
        timing.end();
      }

      appView.setArtProfileCollection(
          appView.getArtProfileCollection().withoutMissingItems(appView));
      assert appView.getStartupProfile().isEmpty();

      finalizeApplication(appView, executor, timing);

      // Add the VarHandle naming lens after synthetic finalization.
      timing.time(
          "Create MethodHandle.Lookup rewriting lens",
          () ->
              appView.setNamingLens(
                  VarHandleDesugaringRewritingNamingLens
                      .createVarHandleDesugaringRewritingNamingLens(appView)));

      timing.end(); // post-converter

      reportSyntheticInformation(appView);

      if (options.isGeneratingClassFiles()) {
        new CfApplicationWriter(appView, marker)
            .write(options.getClassFileConsumer(), executor, inputApp);
      } else {
        ApplicationWriter.create(appView, marker).write(executor, inputApp);
      }
      options.printWarnings();
    } catch (ExecutionException e) {
      throw unwrapExecutionException(e);
    } finally {
      inputApp.signalFinishedToProviders(options.reporter);
      options.signalFinishedToConsumers();
      // Dump timings.
      if (options.printTimes) {
        timing.report();
      }
    }
  }

  private static void reportSyntheticInformation(AppView<?> appView) {
    SyntheticInfoConsumer consumer = appView.options().getSyntheticInfoConsumer();
    if (consumer == null || !appView.options().intermediate) {
      return;
    }
    appView.getSyntheticItems().reportSyntheticsInformation(consumer);
    consumer.finished();
  }

  private static void initializeAssumeInfoCollection(AppView<AppInfo> appView) {
    AssumeInfoCollection.Builder assumeInfoCollectionBuilder = AssumeInfoCollection.builder();
    AbstractValueFactory abstractValueFactory = appView.abstractValueFactory();
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    InternalOptions options = appView.options();
    if (options.isGeneratingDex()) {
      assumeInfoCollectionBuilder
          .meetAssumeValue(
              dexItemFactory.androidOsBuildVersionMembers.SDK_INT,
              abstractValueFactory.createNumberFromIntervalValue(
                  options.getMinApiLevel().getLevel(), Integer.MAX_VALUE))
          .setIsSideEffectFree(dexItemFactory.androidOsBuildVersionMembers.SDK_INT);
    }
    appView.setAssumeInfoCollection(assumeInfoCollectionBuilder.build());
  }

  private static void finalizeApplication(
      AppView<AppInfo> appView, ExecutorService executorService, Timing timing)
      throws ExecutionException {
    timing.time(
        "Finalize synthetics",
        () -> SyntheticFinalization.finalize(appView, timing, executorService));

    timing.time(
        "Horizontal merger",
        () ->
            HorizontalClassMerger.createForD8ClassMerging(appView)
                .runIfNecessary(executorService, timing));

    timing.time(
        "Signature rewriter",
        () ->
            new GenericSignatureRewriter(appView)
                .runForD8(appView.appInfo().classes(), executorService));

    timing.time(
        "Kotlin metadata rewriter",
        () -> new KotlinMetadataRewriter(appView).runForD8(executorService));

    timing.time(
        "Startup instrumentation", () -> StartupInstrumentation.run(appView, executorService));

    timing.time(
        "Api reference stubber", () -> new ApiReferenceStubber(appView).run(executorService));
  }

  private static DexApplication rewriteNonDexInputs(
      AppView<AppInfo> appView,
      AndroidApp inputApp,
      ExecutorService executor,
      Marker marker,
      Timing timing)
      throws IOException, ExecutionException {
    // TODO(b/154575955): Remove the naming lens in D8.
    appView
        .options()
        .reporter
        .warning(
            new StringDiagnostic(
                "The compilation is slowed down due to a mix of class file and dex file inputs in"
                    + " the context of desugared library. This can be fixed by pre-compiling to"
                    + " dex the class file inputs and dex merging only dex files."));
    List<DexProgramClass> dexProgramClasses = new ArrayList<>();
    List<DexProgramClass> nonDexProgramClasses = new ArrayList<>();
    for (DexProgramClass aClass : appView.appInfo().classes()) {
      if (aClass.originatesFromDexResource()) {
        dexProgramClasses.add(aClass);
      } else {
        nonDexProgramClasses.add(aClass);
      }
    }
    DexApplication cfApp =
        appView.app().builder().replaceProgramClasses(nonDexProgramClasses).build();
    appView.setAppInfo(
        new AppInfo(
            appView.appInfo().getSyntheticItems().commit(cfApp),
            appView.appInfo().getMainDexInfo()));
    ConvertedCfFiles convertedCfFiles = new ConvertedCfFiles();
    new GenericSignatureRewriter(appView).run(appView.appInfo().classes(), executor);
    new KotlinMetadataRewriter(appView).runForD8(executor);
    ApplicationWriter.create(appView, marker, convertedCfFiles).write(executor);
    AndroidApp.Builder builder = AndroidApp.builder(inputApp);
    builder.getProgramResourceProviders().clear();
    builder.addProgramResourceProvider(convertedCfFiles);
    AndroidApp newAndroidApp = builder.build();
    DexApplication newApp =
        new ApplicationReader(newAndroidApp, appView.options(), timing).read(executor);
    DexApplication.Builder<?> finalDexApp = newApp.builder();
    for (DexProgramClass dexProgramClass : dexProgramClasses) {
      finalDexApp.addProgramClass(dexProgramClass);
    }
    return finalDexApp.build();
  }

  public static class ConvertedCfFiles implements DexIndexedConsumer, ProgramResourceProvider {

    private final List<ProgramResource> resources = new ArrayList<>();

    @Override
    public synchronized void accept(
        int fileIndex, ByteDataView data, Set<String> descriptors, DiagnosticsHandler handler) {
      // TODO(b/154106502): Map Origin information.
      resources.add(
          ProgramResource.fromBytes(
              Origin.unknown(), ProgramResource.Kind.DEX, data.copyByteData(), descriptors));
    }

    @Override
    public Collection<ProgramResource> getProgramResources() {
      return resources;
    }

    @Override
    public void finished(DiagnosticsHandler handler) {}
  }
}
