// 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.retrace.internal.StackTraceRegularExpressionParser;
import java.util.List;
import java.util.function.Consumer;

@Keep
public class RetraceCommand {

  private final List<String> stackTrace;
  private final Consumer<List<String>> retracedStackTraceConsumer;
  // Not inheriting to allow for static builder methods.
  private final RetraceOptions options;

  private RetraceCommand(
      String regularExpression,
      DiagnosticsHandler diagnosticsHandler,
      ProguardMapProducer proguardMapProducer,
      List<String> stackTrace,
      Consumer<List<String>> retracedStackTraceConsumer,
      boolean isVerbose) {
    this.stackTrace = stackTrace;
    this.retracedStackTraceConsumer = retracedStackTraceConsumer;
    this.options =
        RetraceOptions.builder(diagnosticsHandler)
            .setRegularExpression(regularExpression)
            .setProguardMapProducer(proguardMapProducer)
            .setVerbose(isVerbose)
            .build();

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

  public List<String> getStackTrace() {
    return stackTrace;
  }

  public Consumer<List<String>> getRetracedStackTraceConsumer() {
    return retracedStackTraceConsumer;
  }

  public RetraceOptions getOptions() {
    return options;
  }

  /**
   * 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() {});
  }

  @Keep
  public static class Builder {

    private boolean isVerbose;
    private final DiagnosticsHandler diagnosticsHandler;
    private ProguardMapProducer proguardMapProducer;
    private String regularExpression = StackTraceRegularExpressionParser.DEFAULT_REGULAR_EXPRESSION;
    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. Note, this will
     * override the default regular expression.
     *
     * @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");
      }
      return new RetraceCommand(
          regularExpression,
          diagnosticsHandler,
          proguardMapProducer,
          stackTrace,
          retracedStackTraceConsumer,
          isVerbose);
    }
  }
}
