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

import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.retrace.RetraceClassResult;
import com.android.tools.r8.retrace.RetraceFieldResult;
import com.android.tools.r8.retrace.RetraceFrameResult;
import com.android.tools.r8.retrace.RetraceStackTraceContext;
import com.android.tools.r8.retrace.RetraceStackTraceElementProxy;
import com.android.tools.r8.retrace.RetraceTypeResult;
import com.android.tools.r8.retrace.RetraceTypeResult.Element;
import com.android.tools.r8.retrace.RetracedClassReference;
import com.android.tools.r8.retrace.RetracedFieldReference;
import com.android.tools.r8.retrace.RetracedMethodReference;
import com.android.tools.r8.retrace.RetracedSourceFile;
import com.android.tools.r8.retrace.RetracedTypeReference;
import com.android.tools.r8.retrace.Retracer;
import com.android.tools.r8.retrace.StackTraceElementProxy;
import com.android.tools.r8.retrace.StackTraceElementProxyRetracer;
import com.android.tools.r8.utils.ListUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.OptionalInt;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StackTraceElementProxyRetracerImpl<T, ST extends StackTraceElementProxy<T, ST>>
    implements StackTraceElementProxyRetracer<T, ST> {

  private final Retracer retracer;

  public StackTraceElementProxyRetracerImpl(Retracer retracer) {
    this.retracer = retracer;
  }

  @Override
  public Stream<? extends RetraceStackTraceElementProxy<T, ST>> retrace(
      ST element, RetraceStackTraceContext context) {
    Stream<RetraceStackTraceElementProxyImpl<T, ST>> currentResults =
        Stream.of(RetraceStackTraceElementProxyImpl.create(element, context));
    if (!element.hasClassName()
        && !element.hasFieldOrReturnType()
        && !element.hasMethodArguments()) {
      return currentResults;
    }
    currentResults = retraceFieldOrReturnType(currentResults, element);
    currentResults = retracedMethodArguments(currentResults, element);
    if (element.hasClassName()) {
      RetraceClassResult classResult = retracer.retraceClass(element.getClassReference());
      if (element.hasMethodName()) {
        currentResults = retraceMethod(currentResults, element, classResult);
      } else if (element.hasFieldName()) {
        currentResults = retraceField(currentResults, element, classResult);
      } else {
        currentResults = retraceClassOrType(currentResults, element, classResult);
      }
    }
    return currentResults;
  }

  private Stream<RetraceStackTraceElementProxyImpl<T, ST>> retraceClassOrType(
      Stream<RetraceStackTraceElementProxyImpl<T, ST>> currentResults,
      ST element,
      RetraceClassResult classResult) {
    return currentResults.flatMap(
        proxy ->
            // We assume, since no method was defined for this stack trace element, that this was a
            // thrown exception.
            classResult.lookupThrownException(proxy.getContext()).stream()
                .map(
                    thrownExceptionElement ->
                        proxy
                            .builder()
                            .setRetracedClass(thrownExceptionElement.getRetracedClass())
                            .joinAmbiguous(classResult.isAmbiguous())
                            .setTopFrame(true)
                            .setContext(thrownExceptionElement.getContext())
                            .applyIf(
                                element.hasSourceFile(),
                                builder -> {
                                  RetracedSourceFile sourceFile =
                                      thrownExceptionElement.getSourceFile();
                                  builder.setSourceFile(
                                      sourceFile.hasRetraceResult()
                                          ? sourceFile.getSourceFile()
                                          : RetraceUtils.inferSourceFile(
                                              thrownExceptionElement
                                                  .getRetracedClass()
                                                  .getTypeName(),
                                              element.getSourceFile(),
                                              classResult.hasRetraceResult()));
                                })
                            .build()));
  }

  private Stream<RetraceStackTraceElementProxyImpl<T, ST>> retraceMethod(
      Stream<RetraceStackTraceElementProxyImpl<T, ST>> currentResults,
      ST element,
      RetraceClassResult classResult) {
    return currentResults.flatMap(
        proxy -> {
          RetraceFrameResult frameResult =
              classResult.lookupFrame(
                  proxy.context,
                  element.hasLineNumber()
                      ? OptionalInt.of(element.getLineNumber())
                      : OptionalInt.empty(),
                  element.getMethodName());
          return frameResult.stream()
              .flatMap(
                  frameElement ->
                      frameElement
                          .forEachRewrittenFrame(proxy.getContext())
                          .map(
                              singleFrame -> {
                                boolean isTopFrame = singleFrame.getIndex() == 0;
                                RetracedMethodReference method = singleFrame.getMethodReference();
                                return proxy
                                    .builder()
                                    .setRetracedClass(method.getHolderClass())
                                    .setRetracedMethod(method)
                                    .joinAmbiguous(frameResult.isAmbiguous() && isTopFrame)
                                    .setTopFrame(isTopFrame)
                                    .setContext(frameElement.getContext())
                                    .applyIf(
                                        element.hasLineNumber(),
                                        builder -> {
                                          builder.setLineNumber(
                                              method.getOriginalPositionOrDefault(
                                                  element.getLineNumber()));
                                        })
                                    .applyIf(
                                        element.hasSourceFile(),
                                        builder -> {
                                          RetracedSourceFile sourceFileResult =
                                              frameElement.getSourceFile(method);
                                          builder.setSourceFile(
                                              sourceFileResult.hasRetraceResult()
                                                  ? sourceFileResult.getSourceFile()
                                                  : RetraceUtils.inferSourceFile(
                                                      method.getHolderClass().getTypeName(),
                                                      element.getSourceFile(),
                                                      classResult.hasRetraceResult()));
                                        })
                                    .build();
                              }));
        });
  }

  private Stream<RetraceStackTraceElementProxyImpl<T, ST>> retraceField(
      Stream<RetraceStackTraceElementProxyImpl<T, ST>> currentResults,
      ST element,
      RetraceClassResult classResult) {
    return currentResults.flatMap(
        proxy -> {
          RetraceFieldResult retraceFieldResult = classResult.lookupField(element.getFieldName());
          return retraceFieldResult.stream()
              .map(
                  fieldElement ->
                      proxy
                          .builder()
                          .setRetracedClass(fieldElement.getField().getHolderClass())
                          .setRetracedField(fieldElement.getField())
                          .joinAmbiguous(retraceFieldResult.isAmbiguous())
                          .setTopFrame(true)
                          .applyIf(
                              element.hasSourceFile(),
                              builder -> {
                                RetracedSourceFile sourceFile = fieldElement.getSourceFile();
                                builder.setSourceFile(
                                    sourceFile.hasRetraceResult()
                                        ? sourceFile.getSourceFile()
                                        : RetraceUtils.inferSourceFile(
                                            fieldElement.getField().getHolderClass().getTypeName(),
                                            element.getSourceFile(),
                                            classResult.hasRetraceResult()));
                              })
                          .build());
        });
  }

  private Stream<RetraceStackTraceElementProxyImpl<T, ST>> retraceFieldOrReturnType(
      Stream<RetraceStackTraceElementProxyImpl<T, ST>> currentResults, ST element) {
    if (!element.hasFieldOrReturnType()) {
      return currentResults;
    }
    String elementOrReturnType = element.getFieldOrReturnType();
    if (elementOrReturnType.equals("void")) {
      return currentResults.map(
          proxy ->
              proxy
                  .builder()
                  .setRetracedFieldOrReturnType(RetracedTypeReferenceImpl.createVoid())
                  .build());
    } else {
      TypeReference typeReference = Reference.typeFromTypeName(elementOrReturnType);
      RetraceTypeResult retraceTypeResult = retracer.retraceType(typeReference);
      List<Element> retracedElements = retraceTypeResult.stream().collect(Collectors.toList());
      return currentResults.flatMap(
          proxy ->
              retracedElements.stream()
                  .map(
                      retracedResult ->
                          proxy
                              .builder()
                              .setRetracedFieldOrReturnType(retracedResult.getType())
                              .joinAmbiguous(retraceTypeResult.isAmbiguous())
                              .build()));
    }
  }

  private Stream<RetraceStackTraceElementProxyImpl<T, ST>> retracedMethodArguments(
      Stream<RetraceStackTraceElementProxyImpl<T, ST>> currentResults, ST element) {
    if (!element.hasMethodArguments()) {
      return currentResults;
    }
    List<RetraceTypeResult> retracedResults =
        Arrays.stream(element.getMethodArguments().split(","))
            .map(typeName -> retracer.retraceType(Reference.typeFromTypeName(typeName)))
            .collect(Collectors.toList());
    List<List<RetracedTypeReference>> initial = new ArrayList<>();
    initial.add(new ArrayList<>());
    List<List<RetracedTypeReference>> allRetracedArguments =
        ListUtils.fold(
            retracedResults,
            initial,
            (acc, retracedTypeResult) -> {
              List<List<RetracedTypeReference>> newResult = new ArrayList<>();
              retracedTypeResult.forEach(
                  retracedElement ->
                      acc.forEach(
                          oldResult -> {
                            List<RetracedTypeReference> newList = new ArrayList<>(oldResult);
                            newList.add(retracedElement.getType());
                            newResult.add(newList);
                          }));
              return newResult;
            });
    boolean isAmbiguous = allRetracedArguments.size() > 1;
    return currentResults.flatMap(
        proxy ->
            allRetracedArguments.stream()
                .map(
                    retracedArguments ->
                        proxy
                            .builder()
                            .setRetracedMethodArguments(retracedArguments)
                            .joinAmbiguous(isAmbiguous)
                            .build()));
  }

  public static class RetraceStackTraceElementProxyImpl<T, ST extends StackTraceElementProxy<T, ST>>
      implements RetraceStackTraceElementProxy<T, ST> {

    private final ST originalItem;
    private final RetracedClassReference retracedClass;
    private final RetracedMethodReference retracedMethod;
    private final RetracedFieldReference retracedField;
    private final RetracedTypeReference fieldOrReturnType;
    private final List<RetracedTypeReference> methodArguments;
    private final String sourceFile;
    private final int lineNumber;
    private final boolean isAmbiguous;
    private final boolean isTopFrame;
    private final RetraceStackTraceContext context;

    private RetraceStackTraceElementProxyImpl(
        ST originalItem,
        RetracedClassReference retracedClass,
        RetracedMethodReference retracedMethod,
        RetracedFieldReference retracedField,
        RetracedTypeReference fieldOrReturnType,
        List<RetracedTypeReference> methodArguments,
        String sourceFile,
        int lineNumber,
        boolean isAmbiguous,
        boolean isTopFrame,
        RetraceStackTraceContext context) {
      assert originalItem != null;
      this.originalItem = originalItem;
      this.retracedClass = retracedClass;
      this.retracedMethod = retracedMethod;
      this.retracedField = retracedField;
      this.fieldOrReturnType = fieldOrReturnType;
      this.methodArguments = methodArguments;
      this.sourceFile = sourceFile;
      this.lineNumber = lineNumber;
      this.isAmbiguous = isAmbiguous;
      this.isTopFrame = isTopFrame;
      this.context = context;
    }

    @Override
    public boolean isAmbiguous() {
      return isAmbiguous;
    }

    @Override
    public boolean isTopFrame() {
      return isTopFrame;
    }

    @Override
    public boolean hasRetracedClass() {
      return retracedClass != null;
    }

    @Override
    public boolean hasRetracedMethod() {
      return retracedMethod != null;
    }

    @Override
    public boolean hasRetracedField() {
      return retracedField != null;
    }

    @Override
    public boolean hasSourceFile() {
      return sourceFile != null;
    }

    @Override
    public boolean hasLineNumber() {
      return lineNumber != -1;
    }

    @Override
    public boolean hasFieldOrReturnType() {
      return fieldOrReturnType != null;
    }

    @Override
    public boolean hasMethodArguments() {
      return methodArguments != null;
    }

    @Override
    public ST getOriginalItem() {
      return originalItem;
    }

    @Override
    public RetracedClassReference getRetracedClass() {
      return retracedClass;
    }

    @Override
    public RetracedMethodReference getRetracedMethod() {
      return retracedMethod;
    }

    @Override
    public RetracedFieldReference getRetracedField() {
      return retracedField;
    }

    @Override
    public RetracedTypeReference getRetracedFieldOrReturnType() {
      return fieldOrReturnType;
    }

    @Override
    public List<RetracedTypeReference> getMethodArguments() {
      return methodArguments;
    }

    @Override
    public String getSourceFile() {
      return sourceFile;
    }

    private static <T, ST extends StackTraceElementProxy<T, ST>>
        RetraceStackTraceElementProxyImpl<T, ST> create(
            ST originalItem, RetraceStackTraceContext context) {
      return new RetraceStackTraceElementProxyImpl<T, ST>(
          originalItem, null, null, null, null, null, null, -1, false, false, context);
    }

    private Builder<T, ST> builder() {
      Builder<T, ST> builder = new Builder<>(originalItem);
      builder.classContext = retracedClass;
      builder.methodContext = retracedMethod;
      builder.retracedField = retracedField;
      builder.fieldOrReturnType = fieldOrReturnType;
      builder.methodArguments = methodArguments;
      builder.sourceFile = sourceFile;
      builder.lineNumber = lineNumber;
      builder.isAmbiguous = isAmbiguous;
      builder.isTopFrame = isTopFrame;
      builder.context = context;
      return builder;
    }

    @Override
    public int getLineNumber() {
      return lineNumber;
    }

    @Override
    public RetraceStackTraceContext getContext() {
      return context;
    }

    @Override
    public int compareTo(RetraceStackTraceElementProxy<T, ST> other) {
      int classCompare = Boolean.compare(hasRetracedClass(), other.hasRetracedClass());
      if (classCompare != 0) {
        return classCompare;
      }
      if (hasRetracedClass()) {
        classCompare =
            getRetracedClass().getTypeName().compareTo(other.getRetracedClass().getTypeName());
        if (classCompare != 0) {
          return classCompare;
        }
      }
      int methodCompare = Boolean.compare(hasRetracedMethod(), other.hasRetracedMethod());
      if (methodCompare != 0) {
        return methodCompare;
      }
      if (hasRetracedMethod()) {
        methodCompare = getRetracedMethod().compareTo(other.getRetracedMethod());
        if (methodCompare != 0) {
          return methodCompare;
        }
      }
      int sourceFileCompare = Boolean.compare(hasSourceFile(), other.hasSourceFile());
      if (sourceFileCompare != 0) {
        return sourceFileCompare;
      }
      if (hasSourceFile()) {
        sourceFileCompare = getSourceFile().compareTo(other.getSourceFile());
        if (sourceFileCompare != 0) {
          return sourceFileCompare;
        }
      }
      int lineNumberCompare = Boolean.compare(hasLineNumber(), other.hasLineNumber());
      if (lineNumberCompare != 0) {
        return lineNumberCompare;
      }
      if (hasLineNumber()) {
        return Integer.compare(lineNumber, other.getLineNumber());
      }
      return 0;
    }

    private static class Builder<T, ST extends StackTraceElementProxy<T, ST>> {

      private final ST originalElement;
      private RetracedClassReference classContext;
      private RetracedMethodReference methodContext;
      private RetracedFieldReference retracedField;
      private RetracedTypeReference fieldOrReturnType;
      private List<RetracedTypeReference> methodArguments;
      private String sourceFile;
      private int lineNumber = -1;
      private boolean isAmbiguous;
      private boolean isTopFrame;
      private RetraceStackTraceContext context;

      private Builder(ST originalElement) {
        this.originalElement = originalElement;
      }

      private Builder<T, ST> setRetracedClass(RetracedClassReference retracedClass) {
        this.classContext = retracedClass;
        return this;
      }

      private Builder<T, ST> setRetracedMethod(RetracedMethodReference methodElement) {
        this.methodContext = methodElement;
        return this;
      }

      private Builder<T, ST> setRetracedField(RetracedFieldReference retracedField) {
        this.retracedField = retracedField;
        return this;
      }

      private Builder<T, ST> setRetracedFieldOrReturnType(RetracedTypeReference retracedType) {
        this.fieldOrReturnType = retracedType;
        return this;
      }

      private Builder<T, ST> setRetracedMethodArguments(List<RetracedTypeReference> arguments) {
        this.methodArguments = arguments;
        return this;
      }

      private Builder<T, ST> setSourceFile(String sourceFile) {
        this.sourceFile = sourceFile;
        return this;
      }

      private Builder<T, ST> setLineNumber(int lineNumber) {
        this.lineNumber = lineNumber;
        return this;
      }

      private Builder<T, ST> joinAmbiguous(boolean ambiguous) {
        this.isAmbiguous = ambiguous || this.isAmbiguous;
        return this;
      }

      private Builder<T, ST> setTopFrame(boolean topFrame) {
        isTopFrame = topFrame;
        return this;
      }

      private Builder<T, ST> setContext(RetraceStackTraceContext context) {
        this.context = context;
        return this;
      }

      private Builder<T, ST> applyIf(boolean condition, Consumer<Builder<T, ST>> consumer) {
        if (condition) {
          consumer.accept(this);
        }
        return this;
      }

      private RetraceStackTraceElementProxyImpl<T, ST> build() {
        RetracedClassReference retracedClass = classContext;
        if (methodContext != null) {
          retracedClass = methodContext.getHolderClass();
        }
        return new RetraceStackTraceElementProxyImpl<>(
            originalElement,
            retracedClass,
            methodContext,
            retracedField,
            fieldOrReturnType,
            methodArguments,
            sourceFile,
            lineNumber,
            isAmbiguous,
            isTopFrame,
            context);
      }
    }
  }
}
