// 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.RetraceFieldElement;
import com.android.tools.r8.retrace.RetraceFieldResult;
import com.android.tools.r8.retrace.RetraceFrameElement;
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.RetraceStackTraceElementProxyResult;
import com.android.tools.r8.retrace.RetraceThrownExceptionElement;
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.RetracedSingleFrame;
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.Box;
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.function.Supplier;
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 RetraceStackTraceElementProxyResult<T, ST> retrace(
      ST element, RetraceStackTraceContext context) {
    RetraceStackTraceElementProxyResultImpl<T, ST> currentResult =
        RetraceStackTraceElementProxyResultImpl.Builder.<T, ST>create()
            .setResultStream(Stream.of(RetraceStackTraceElementProxyImpl.create(element, context)))
            .setResultContext(RetraceStackTraceContext::empty)
            .build();
    if (!element.hasClassName()
        && !element.hasFieldOrReturnType()
        && !element.hasMethodArguments()) {
      return currentResult;
    }
    currentResult = retraceFieldOrReturnType(currentResult, element);
    currentResult = retracedMethodArguments(currentResult, element);
    if (element.hasClassName()) {
      RetraceClassResult classResult = retracer.retraceClass(element.getClassReference());
      if (element.hasMethodName()) {
        currentResult = retraceMethod(currentResult, element, classResult, context);
      } else if (element.hasFieldName()) {
        currentResult = retraceField(currentResult, element, classResult);
      } else {
        currentResult = retraceClassOrType(currentResult, classResult);
      }
    }
    return currentResult;
  }

  private RetraceStackTraceElementProxyResultImpl<T, ST> retraceClassOrType(
      RetraceStackTraceElementProxyResultImpl<T, ST> currentResult,
      RetraceClassResult classResult) {
    return currentResult
        .builder()
        .setResultStream(
            currentResult.stream()
                .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 ->
                                    buildProxyForRewrittenThrownExceptionElement(
                                        classResult, proxy, thrownExceptionElement))))
        .build();
  }

  private RetraceStackTraceElementProxyImpl<T, ST> buildProxyForRewrittenThrownExceptionElement(
      RetraceClassResult classResult,
      RetraceStackTraceElementProxyImpl<T, ST> proxy,
      RetraceThrownExceptionElement thrownExceptionElement) {
    return proxy
        .builder()
        .setRetracedClass(thrownExceptionElement.getRetracedClass())
        .joinAmbiguous(classResult.isAmbiguous())
        .setTopFrame(true)
        .setContext(thrownExceptionElement.getContext())
        .apply(
            setSourceFileOnProxy(
                thrownExceptionElement::getSourceFile,
                thrownExceptionElement.getRetracedClass(),
                classResult))
        .build();
  }

  private RetraceStackTraceElementProxyResultImpl<T, ST> retraceMethod(
      RetraceStackTraceElementProxyResultImpl<T, ST> currentResult,
      ST element,
      RetraceClassResult classResult,
      RetraceStackTraceContext context) {
    Box<RetraceStackTraceContext> resultingContext = new Box<>(RetraceStackTraceContext.empty());
    RetraceStackTraceElementProxyResultImpl.Builder<T, ST> resultBuilder =
        currentResult.builder().setResultContext(resultingContext::get);
    return resultBuilder
        .setResultStream(
            currentResult.stream()
                .flatMap(
                    proxy -> {
                      RetraceFrameResult frameResult =
                          classResult.lookupFrame(
                              context,
                              element.hasLineNumber()
                                  ? OptionalInt.of(element.getLineNumber())
                                  : OptionalInt.empty(),
                              element.getMethodName());
                      if (!frameResult.isEmpty()) {
                        return classResult.stream()
                            .map(
                                classElement ->
                                    proxy
                                        .builder()
                                        .setTopFrame(true)
                                        .joinAmbiguous(classResult.isAmbiguous())
                                        .setRetracedClass(classElement.getRetracedClass())
                                        .applyIf(
                                            element.hasLineNumber(),
                                            b -> b.setLineNumber(element.getLineNumber()))
                                        .apply(
                                            setSourceFileOnProxy(
                                                classElement::getSourceFile,
                                                classElement.getRetracedClass(),
                                                classResult))
                                        .build());
                      }
                      return frameResult.stream()
                          .flatMap(
                              frameElement -> {
                                resultingContext.set(frameElement.getRetraceStackTraceContext());
                                return frameElement
                                    .streamRewritten(context)
                                    .map(
                                        singleFrame ->
                                            buildProxyForRewrittenFrameElement(
                                                element,
                                                classResult,
                                                proxy,
                                                frameResult,
                                                frameElement,
                                                singleFrame));
                              });
                    }))
        .build();
  }

  private RetraceStackTraceElementProxyImpl<T, ST> buildProxyForRewrittenFrameElement(
      ST element,
      RetraceClassResult classResult,
      RetraceStackTraceElementProxyImpl<T, ST> proxy,
      RetraceFrameResult frameResult,
      RetraceFrameElement frameElement,
      RetracedSingleFrame singleFrame) {
    boolean isTopFrame = singleFrame.getIndex() == 0;
    RetracedMethodReference method = singleFrame.getMethodReference();
    return proxy
        .builder()
        .setRetracedClass(method.getHolderClass())
        .setRetracedMethod(method)
        .joinAmbiguous(frameResult.isAmbiguous())
        .setTopFrame(isTopFrame)
        .setContext(frameElement.getRetraceStackTraceContext())
        .applyIf(
            element.hasLineNumber(),
            builder -> {
              builder.setLineNumber(method.getOriginalPositionOrDefault(element.getLineNumber()));
            })
        .apply(
            setSourceFileOnProxy(
                () -> frameElement.getSourceFile(method), method.getHolderClass(), classResult))
        .build();
  }

  private RetraceStackTraceElementProxyResultImpl<T, ST> retraceField(
      RetraceStackTraceElementProxyResultImpl<T, ST> currentResult,
      ST element,
      RetraceClassResult classResult) {
    return currentResult
        .builder()
        .setResultStream(
            currentResult.stream()
                .flatMap(
                    proxy -> {
                      RetraceFieldResult retraceFieldResult =
                          classResult.lookupField(element.getFieldName());
                      return retraceFieldResult.stream()
                          .map(
                              fieldElement ->
                                  buildProxyForRewrittenFieldElement(
                                      classResult, proxy, retraceFieldResult, fieldElement));
                    }))
        .build();
  }

  private RetraceStackTraceElementProxyImpl<T, ST> buildProxyForRewrittenFieldElement(
      RetraceClassResult classResult,
      RetraceStackTraceElementProxyImpl<T, ST> proxy,
      RetraceFieldResult retraceFieldResult,
      RetraceFieldElement fieldElement) {
    return proxy
        .builder()
        .setRetracedClass(fieldElement.getField().getHolderClass())
        .setRetracedField(fieldElement.getField())
        .joinAmbiguous(retraceFieldResult.isAmbiguous())
        .setTopFrame(true)
        .apply(
            setSourceFileOnProxy(
                fieldElement::getSourceFile, fieldElement.getField().getHolderClass(), classResult))
        .build();
  }

  private Consumer<RetraceStackTraceElementProxyImpl.Builder<T, ST>> setSourceFileOnProxy(
      Supplier<RetracedSourceFile> sourceFile,
      RetracedClassReference classReference,
      RetraceClassResult classResult) {
    return proxy -> {
      ST original = proxy.originalElement;
      if (!original.hasSourceFile()) {
        return;
      }
      RetracedSourceFile retracedSourceFile = sourceFile.get();
      proxy.setSourceFile(
          retracedSourceFile.hasRetraceResult()
              ? retracedSourceFile.getSourceFile()
              : RetraceUtils.inferSourceFile(
                  classReference.getTypeName(), original.getSourceFile(), classResult.isEmpty()));
    };
  }

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

  private RetraceStackTraceElementProxyImpl<T, ST> buildProxyForRewrittenReturnType(
      RetraceStackTraceElementProxyImpl<T, ST> proxy,
      RetracedTypeReference type,
      boolean isAmbiguous) {
    return proxy.builder().setRetracedFieldOrReturnType(type).joinAmbiguous(isAmbiguous).build();
  }

  private RetraceStackTraceElementProxyResultImpl<T, ST> retracedMethodArguments(
      RetraceStackTraceElementProxyResultImpl<T, ST> currentResult, ST element) {
    if (!element.hasMethodArguments()) {
      return currentResult;
    }
    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 currentResult
        .builder()
        .setResultStream(
            currentResult.stream()
                .flatMap(
                    proxy ->
                        allRetracedArguments.stream()
                            .map(
                                retracedArguments ->
                                    proxy
                                        .builder()
                                        .setRetracedMethodArguments(retracedArguments)
                                        .joinAmbiguous(isAmbiguous)
                                        .build())))
        .build();
  }

  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 hasRetracedFieldOrReturnType() {
      return fieldOrReturnType != null;
    }

    @Override
    public boolean hasRetracedMethodArguments() {
      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> getRetracedMethodArguments() {
      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);
    }

    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) {
      if (this == other) {
        return 0;
      }
      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> apply(Consumer<Builder<T, ST>> consumer) {
        consumer.accept(this);
        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);
      }
    }
  }
}
