// Copyright (c) 2017, the Rex 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.StringUtils.quote;

import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
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.ListUtils;
import com.android.tools.r8.utils.MarkerInfoConsumerDataImpl;
import com.android.tools.r8.utils.MarkerInfoImpl;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.Timing;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

/**
 * A tool to extract markers generated by the R8 compiler and related tools.
 *
 * <p>The tool is run by defining a consumer and then building the command, such as:
 *
 * <pre>
 *   ExtractMarker.run(ExtractMarkerCommand.builder()
 *       .addProgramFiles(inputPathA, inputPathB)
 *       .setMarkerInfoConsumer(new MyInfoConsumer())
 *       .build());
 * </pre>
 */
@KeepForApi
public class ExtractMarker {

  private static class MarkerInfoPrintConsumer implements MarkerInfoConsumer {

    private final PrintStream stream;

    public MarkerInfoPrintConsumer(PrintStream stream) {
      this.stream = stream;
    }

    private void printRow(Origin inputOrigin, String rawMarker) {
      stream.print(inputOrigin.toString());
      stream.print(": ");
      stream.print(rawMarker);
      stream.println();
    }

    @Override
    public void acceptMarkerInfo(MarkerInfoConsumerData data) {
      if (data.hasMarkers()) {
        for (MarkerInfo marker : data.getMarkers()) {
          printRow(data.getInputOrigin(), marker.getRawEncoding());
        }
      } else {
        printRow(data.getInputOrigin(), quote("no marker"));
      }
    }

    @Override
    public void finished() {}
  }

  private static class InterceptedException extends RuntimeException {
    private final CompilationFailedException compilationFailedException;

    private InterceptedException(CompilationFailedException e) {
      this.compilationFailedException = e;
    }
  }

  private static Collection<Marker> extractMarker(AndroidApp app) throws IOException {
    InternalOptions options = new InternalOptions();
    options.skipReadingDexCode = true;
    options.setMinApiLevel(AndroidApiLevel.P);
    DexApplication dexApp = new ApplicationReader(app, options, new Timing("ExtractMarker")).read();
    return dexApp.dexItemFactory.extractMarkers();
  }

  private static void extractForConsumer(
      MarkerInfoConsumer consumer, Reporter reporter, Origin origin, AndroidApp.Builder builder) {
    List<Marker> markers = new ArrayList<>();
    try {
      ExceptionUtils.withCompilationHandler(
          reporter, () -> markers.addAll(extractMarker(builder.build())));
    } catch (CompilationFailedException e) {
      throw new InterceptedException(e);
    }
    // Ensure the markers are sorted, so we have deterministic callback/print order.
    markers.sort(Comparator.comparing(Marker::toString));
    List<MarkerInfo> infos = ListUtils.map(markers, MarkerInfoImpl::new);
    consumer.acceptMarkerInfo(new MarkerInfoConsumerDataImpl(origin, infos));
  }

  /**
   * Main API entry for the extract marker tool.
   *
   * @param command Extract marker command specification.
   */
  public static void run(ExtractMarkerCommand command) throws CompilationFailedException {
    MarkerInfoConsumer consumer = command.getMarkerInfoConsumer();
    Reporter reporter = new Reporter(command.getDiagnosticsHandler());
    try {
      command.forEachEntry(
          (path, origin) ->
              extractForConsumer(
                  consumer, reporter, origin, AndroidApp.builder().addProgramFile(path)),
          (data, origin) ->
              extractForConsumer(
                  consumer, reporter, origin, AndroidApp.builder().addDexProgramData(data, origin)),
          (data, origin) ->
              extractForConsumer(
                  consumer,
                  reporter,
                  origin,
                  AndroidApp.builder().addClassProgramData(data, origin)));
    } catch (InterceptedException e) {
      throw e.compilationFailedException;
    }
  }

  private static void run(String[] args) throws CompilationFailedException {
    PrintStream out = System.out;
    ExtractMarkerCommand.Builder builder = ExtractMarkerCommand.parse(args);
    MarkerInfoConsumer consumer = new MarkerInfoPrintConsumer(out);
    ExtractMarkerCommand command = builder.setMarkerInfoConsumer(consumer).build();
    if (command.isPrintHelp()) {
      System.out.println(ExtractMarkerCommand.USAGE_MESSAGE);
      return;
    }
    run(command);
  }

  /**
   * Command-line entry to the extract marker tool.
   *
   * <p>See {@link ExtractMarkerCommand#USAGE_MESSAGE} or run with {@code --help} for usage
   * information.
   */
  public static void main(String[] args) throws Exception {
    ExceptionUtils.withMainProgramHandler(() -> run(args));
  }
}
