// 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.retrace;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
import com.android.tools.r8.utils.StringDiagnostic;
import java.io.IOException;
import java.util.List;
import java.util.function.Consumer;

public class RetraceCommand {

  final boolean isVerbose;
  final String regularExpression;
  final DiagnosticsHandler diagnosticsHandler;
  final ProguardMapProducer proguardMapProducer;
  final List<String> stackTrace;
  final Consumer<List<String>> retracedStackTraceConsumer;

  private RetraceCommand(
      boolean isVerbose,
      String regularExpression,
      DiagnosticsHandler diagnosticsHandler,
      ProguardMapProducer proguardMapProducer,
      List<String> stackTrace,
      Consumer<List<String>> retracedStackTraceConsumer) {
    this.isVerbose = isVerbose;
    this.regularExpression = regularExpression;
    this.diagnosticsHandler = diagnosticsHandler;
    this.proguardMapProducer = proguardMapProducer;
    this.stackTrace = stackTrace;
    this.retracedStackTraceConsumer = retracedStackTraceConsumer;

    assert this.diagnosticsHandler != null;
    assert this.proguardMapProducer != null;
    assert this.stackTrace != null;
    assert this.retracedStackTraceConsumer != null;
  }

  public boolean printTimes() {
    return System.getProperty("com.android.tools.r8.printtimes") != null;
  }

  public boolean printMemory() {
    return System.getProperty("com.android.tools.r8.printmemory") != null;
  }

  /**
   * Utility method for obtaining a RetraceCommand builder.
   *
   * @param diagnosticsHandler The diagnostics handler for consuming messages.
   */
  public static Builder builder(DiagnosticsHandler diagnosticsHandler) {
    return new Builder(diagnosticsHandler);
  }

  /** Utility method for obtaining a RetraceCommand builder with a default diagnostics handler. */
  public static Builder builder() {
    return new Builder(new DiagnosticsHandler() {});
  }

  public static class Builder {

    private boolean isVerbose;
    private final DiagnosticsHandler diagnosticsHandler;
    private ProguardMapProducer proguardMapProducer;
    private String regularExpression;
    private List<String> stackTrace;
    private Consumer<List<String>> retracedStackTraceConsumer;

    private Builder(DiagnosticsHandler diagnosticsHandler) {
      this.diagnosticsHandler = diagnosticsHandler;
    }

    /** Set if the produced stack trace should have additional information. */
    public Builder setVerbose(boolean verbose) {
      this.isVerbose = verbose;
      return this;
    }

    /**
     * Set a producer for the proguard mapping contents.
     *
     * @param producer Producer for
     */
    public Builder setProguardMapProducer(ProguardMapProducer producer) {
      this.proguardMapProducer = producer;
      return this;
    }

    /**
     * Set a regular expression for parsing the incoming text. The Regular expression must not use
     * naming groups and has special wild cards according to proguard retrace.
     *
     * @param regularExpression The regular expression to use.
     */
    public Builder setRegularExpression(String regularExpression) {
      this.regularExpression = regularExpression;
      return this;
    }

    /**
     * Set the obfuscated stack trace that is to be retraced.
     *
     * @param stackTrace Stack trace having the top entry(the closest stack to the error) as the
     *     first line.
     */
    public Builder setStackTrace(List<String> stackTrace) {
      this.stackTrace = stackTrace;
      return this;
    }

    /**
     * Set a consumer for receiving the retraced stack trace.
     *
     * @param consumer Consumer for receiving the retraced stack trace.
     */
    public Builder setRetracedStackTraceConsumer(Consumer<List<String>> consumer) {
      this.retracedStackTraceConsumer = consumer;
      return this;
    }

    public RetraceCommand build() {
      if (this.diagnosticsHandler == null) {
        throw new RuntimeException("DiagnosticsHandler not specified");
      }
      if (this.proguardMapProducer == null) {
        throw new RuntimeException("ProguardMapSupplier not specified");
      }
      if (this.stackTrace == null) {
        throw new RuntimeException("StackTrace not specified");
      }
      if (this.retracedStackTraceConsumer == null) {
        throw new RuntimeException("RetracedStackConsumer not specified");
      }
      if (isVerbose && regularExpression != null) {
        this.diagnosticsHandler.warning(
            new StringDiagnostic(
                "Retrace does not support verbose output when a regular expression is specified"));
      }
      return new RetraceCommand(
          isVerbose,
          regularExpression,
          diagnosticsHandler,
          proguardMapProducer,
          stackTrace,
          retracedStackTraceConsumer);
    }
  }

  @Keep
  public interface ProguardMapProducer {
    String get() throws IOException;
  }
}
