// Copyright (c) 2020, 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 static com.android.tools.r8.retrace.PlainStackTraceVisitor.firstNonWhiteSpaceCharacterFromIndex;
import static com.android.tools.r8.retrace.StackTraceElementStringProxy.StringIndex.noIndex;

import com.android.tools.r8.retrace.StackTraceElementProxyRetracer.RetraceStackTraceProxy;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;

public final class StackTraceElementStringProxy extends StackTraceElementProxy<String> {

  private final String line;
  private final List<StringIndex> orderedIndices;
  private final StringIndex className;
  private final StringIndex methodName;
  private final StringIndex sourceFile;
  private final StringIndex lineNumber;

  private StackTraceElementStringProxy(
      String line,
      List<StringIndex> orderedIndices,
      StringIndex className,
      StringIndex methodName,
      StringIndex sourceFile,
      StringIndex lineNumber) {
    this.line = line;
    this.orderedIndices = orderedIndices;
    this.className = className;
    this.methodName = methodName;
    this.sourceFile = sourceFile;
    this.lineNumber = lineNumber;
  }

  static StackTraceElementStringProxyBuilder builder(String line) {
    return new StackTraceElementStringProxyBuilder(line);
  }

  @Override
  public boolean hasClassName() {
    return className.hasIndex();
  }

  @Override
  public boolean hasMethodName() {
    return methodName.hasIndex();
  }

  @Override
  public boolean hasFileName() {
    return sourceFile.hasIndex();
  }

  @Override
  public boolean hasLineNumber() {
    return lineNumber.hasIndex();
  }

  @Override
  public String className() {
    return hasClassName() ? getEntryInLine(className) : null;
  }

  @Override
  public String methodName() {
    return hasMethodName() ? getEntryInLine(methodName) : null;
  }

  @Override
  public String fileName() {
    return hasFileName() ? getEntryInLine(sourceFile) : null;
  }

  @Override
  public int lineNumber() {
    if (!hasLineNumber()) {
      return -1;
    }
    try {
      return Integer.parseInt(getEntryInLine(lineNumber));
    } catch (NumberFormatException nfe) {
      return -1;
    }
  }

  public String toRetracedItem(
      RetraceStackTraceProxy<StackTraceElementStringProxy> retracedProxy, boolean printAmbiguous) {
    StringBuilder sb = new StringBuilder();
    int lastSeenIndex = 0;
    if (retracedProxy.isAmbiguous() && printAmbiguous) {
      lastSeenIndex = firstNonWhiteSpaceCharacterFromIndex(line, 0);
      sb.append(line, 0, lastSeenIndex);
      sb.append("<OR> ");
    }
    for (StringIndex index : orderedIndices) {
      sb.append(line, lastSeenIndex, index.startIndex);
      sb.append(index.retracedString.apply(retracedProxy, this));
      lastSeenIndex = index.endIndex;
    }
    sb.append(line, lastSeenIndex, line.length());
    return sb.toString();
  }

  public String lineNumberAsString() {
    return getEntryInLine(lineNumber);
  }

  private String getEntryInLine(StringIndex index) {
    assert index != noIndex();
    return line.substring(index.startIndex, index.endIndex);
  }

  public static class StackTraceElementStringProxyBuilder {

    private final String line;
    private final List<StringIndex> orderedIndices = new ArrayList<>();
    private StringIndex className = noIndex();
    private StringIndex methodName = noIndex();
    private StringIndex sourceFile = noIndex();
    private StringIndex lineNumber = noIndex();
    private int lastSeenStartIndex = -1;

    private StackTraceElementStringProxyBuilder(String line) {
      this.line = line;
    }

    public StackTraceElementStringProxyBuilder registerClassName(int startIndex, int endIndex) {
      ensureLineIndexIncreases(startIndex);
      className =
          new StringIndex(
              startIndex,
              endIndex,
              (retraced, original) -> {
                assert retraced.hasRetracedClass();
                return retraced.getRetracedClass().getTypeName();
              });
      orderedIndices.add(className);
      return this;
    }

    public StackTraceElementStringProxyBuilder registerMethodName(int startIndex, int endIndex) {
      methodName =
          new StringIndex(
              startIndex,
              endIndex,
              (retraced, original) ->
                  retraced.hasRetracedMethod()
                      ? retraced.getRetracedMethod().getMethodName()
                      : original.methodName());
      orderedIndices.add(methodName);
      return this;
    }

    public StackTraceElementStringProxyBuilder registerSourceFile(int startIndex, int endIndex) {
      sourceFile =
          new StringIndex(
              startIndex,
              endIndex,
              (retraced, original) ->
                  retraced.hasSourceFile() ? retraced.getSourceFile() : original.fileName());
      orderedIndices.add(sourceFile);
      return this;
    }

    public StackTraceElementStringProxyBuilder registerLineNumber(int startIndex, int endIndex) {
      lineNumber =
          new StringIndex(
              startIndex,
              endIndex,
              (retraced, original) ->
                  retraced.hasLineNumber()
                      ? retraced.getLineNumber() + ""
                      : original.lineNumberAsString());
      orderedIndices.add(lineNumber);
      return this;
    }

    public StackTraceElementStringProxy build() {
      return new StackTraceElementStringProxy(
          line, orderedIndices, className, methodName, sourceFile, lineNumber);
    }

    private void ensureLineIndexIncreases(int newStartIndex) {
      if (lastSeenStartIndex >= newStartIndex) {
        throw new RuntimeException("Parsing has to be incremental in the order of characters.");
      }
      lastSeenStartIndex = newStartIndex;
    }
  }

  static final class StringIndex {

    private static final StringIndex NO_INDEX = new StringIndex(-1, -1, null);

    static StringIndex noIndex() {
      return NO_INDEX;
    }

    private final int startIndex;
    private final int endIndex;
    private final BiFunction<
            RetraceStackTraceProxy<StackTraceElementStringProxy>,
            StackTraceElementStringProxy,
            String>
        retracedString;

    private StringIndex(
        int startIndex,
        int endIndex,
        BiFunction<
                RetraceStackTraceProxy<StackTraceElementStringProxy>,
                StackTraceElementStringProxy,
                String>
            retracedString) {
      this.startIndex = startIndex;
      this.endIndex = endIndex;
      this.retracedString = retracedString;
    }

    boolean hasIndex() {
      return this != NO_INDEX;
    }
  }
}
