// Copyright (c) 2019, 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.dex.ApplicationReader;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.LazyLoadedDexApplication;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.desugar.TypeRewriter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAmender;
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.shaking.AnnotationRemover;
import com.android.tools.r8.shaking.L8TreePruner;
import com.android.tools.r8.synthesis.SyntheticFinalization;
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.SelfRetraceTest;
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.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

/**
 * The L8 compiler.
 */
@Keep
public class L8 {

  /**
   * Main API entry for the L8 compiler.
   *
   * @param command L8 command.
   */
  public static void run(L8Command command) throws CompilationFailedException {
    runForTesting(
        command.getInputApp(),
        command.getInternalOptions(),
        command.isShrinking(),
        command.getD8Command(),
        command.getR8Command());
  }

  /**
   * Main API entry for the L8 compiler.
   *
   * @param command L8 command.
   * @param executor executor service from which to get threads for multi-threaded processing.
   */
  public static void run(L8Command command, ExecutorService executor)
      throws CompilationFailedException {
    run(
        command.getInputApp(),
        command.getInternalOptions(),
        command.isShrinking(),
        command.getD8Command(),
        command.getR8Command(),
        executor);
  }

  static void runForTesting(
      AndroidApp app,
      InternalOptions options,
      boolean shrink,
      D8Command d8Command,
      R8Command r8Command)
      throws CompilationFailedException {
    ExecutorService executorService = ThreadUtils.getExecutorService(options);
    run(app, options, shrink, d8Command, r8Command, executorService);
  }

  private static void run(
      AndroidApp app,
      InternalOptions options,
      boolean shrink,
      D8Command d8Command,
      R8Command r8Command,
      ExecutorService executorService)
      throws CompilationFailedException {
    try {
      assert !options.cfToCfDesugar;
      ExceptionUtils.withD8CompilationHandler(
          options.reporter,
          () -> {
            // Desugar to class file format and turn off switch optimizations, as the final
            // compilation with D8 or R8 will do that.
            options.cfToCfDesugar = true;
            assert !options.forceAnnotateSynthetics;
            options.forceAnnotateSynthetics = true;
            assert options.enableSwitchRewriting;
            options.enableSwitchRewriting = false;
            assert options.enableStringSwitchConversion;
            options.enableStringSwitchConversion = false;

            desugar(app, options, executorService);

            options.cfToCfDesugar = false;
            options.forceAnnotateSynthetics = false;
            options.enableSwitchRewriting = true;
            options.enableStringSwitchConversion = true;
          });
      assert !options.cfToCfDesugar;
      if (shrink) {
        R8.run(r8Command, executorService);
      } else if (d8Command != null) {
        D8.run(d8Command, executorService);
      }
    } finally {
      executorService.shutdown();
    }
  }

  private static void desugar(
      AndroidApp inputApp, InternalOptions options, ExecutorService executor) throws IOException {
    Timing timing = Timing.create("L8 desugaring", options);
    assert options.cfToCfDesugar;
    try {
      // Since L8 Cf representation is temporary, just disable long running back-end optimizations
      // on it.
      options.enableLoadStoreOptimization = false;

      AppView<AppInfo> appView = readApp(inputApp, options, executor, timing);
      DesugaredLibraryAmender.run(appView);

      if (!options.disableL8AnnotationRemoval) {
        AnnotationRemover.clearAnnotations(appView);
      }

      new IRConverter(appView, timing).convert(appView, executor);

      SyntheticFinalization.finalize(appView, executor);

      NamingLens namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView);
      new GenericSignatureRewriter(appView, namingLens).run(appView.appInfo().classes(), executor);

      new CfApplicationWriter(appView, options.getMarker(Tool.L8), namingLens)
          .write(options.getClassFileConsumer());
      options.printWarnings();
    } catch (ExecutionException e) {
      throw unwrapExecutionException(e);
    } finally {
      options.signalFinishedToConsumers();
      // Dump timings.
      if (options.printTimes) {
        timing.report();
      }
    }
  }

  private static AppView<AppInfo> readApp(
      AndroidApp inputApp, InternalOptions options, ExecutorService executor, Timing timing)
      throws IOException {
    LazyLoadedDexApplication lazyApp =
        new ApplicationReader(inputApp, options, timing).read(executor);
    options.loadMachineDesugaredLibrarySpecification(timing, lazyApp);
    TypeRewriter typeRewriter = options.getTypeRewriter();

    DexApplication app = new L8TreePruner(options).prune(lazyApp, typeRewriter);
    return AppView.createForL8(
        AppInfo.createInitialAppInfo(app, GlobalSyntheticsStrategy.forSingleOutputMode()),
        typeRewriter);
  }

  private static void run(String[] args) throws CompilationFailedException {
    L8Command command = L8Command.parse(args, CommandLineOrigin.INSTANCE).build();
    if (command.isPrintHelp()) {
      SelfRetraceTest.test();
      System.out.println(L8CommandParser.getUsageMessage());
      return;
    }
    if (command.isPrintVersion()) {
      System.out.println("L8 " + Version.getVersionString());
      return;
    }
    run(command);
  }

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