// 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.RetraceStackTraceProxy;
import com.android.tools.r8.retrace.RetraceTypeResult;
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.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.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<RetraceStackTraceProxy<T, ST>> retrace(ST element) {
    if (!element.hasClassName()) {
      RetraceStackTraceProxyImpl.Builder<T, ST> builder =
          RetraceStackTraceProxyImpl.builder(element);
      return Stream.of(builder.build());
    }
    RetraceClassResult classResult = retracer.retraceClass(element.getClassReference());
    if (element.hasMethodName()) {
      return retraceMethod(element, classResult);
    } else if (element.hasFieldName()) {
      return retraceField(element, classResult);
    } else {
      return retraceClassOrType(element, classResult);
    }
  }

  private Stream<RetraceStackTraceProxy<T, ST>> retraceClassOrType(
      ST element, RetraceClassResult classResult) {
    return classResult.stream()
        .flatMap(
            classElement ->
                retraceFieldOrReturnType(element)
                    .flatMap(
                        fieldOrReturnTypeConsumer ->
                            retracedMethodArguments(element)
                                .map(
                                    argumentsConsumer -> {
                                      RetraceStackTraceProxyImpl.Builder<T, ST> proxy =
                                          RetraceStackTraceProxyImpl.builder(element)
                                              .setRetracedClass(classElement.getRetracedClass())
                                              .setAmbiguous(classResult.isAmbiguous())
                                              .setTopFrame(true);
                                      argumentsConsumer.accept(proxy);
                                      fieldOrReturnTypeConsumer.accept(proxy);
                                      if (element.hasFileName()) {
                                        proxy.setSourceFile(
                                            classElement
                                                .retraceSourceFile(element.getFileName())
                                                .getFilename());
                                      }
                                      return proxy.build();
                                    })));
  }

  private Stream<RetraceStackTraceProxy<T, ST>> retraceMethod(
      ST element, RetraceClassResult classResult) {
    return retraceFieldOrReturnType(element)
        .flatMap(
            fieldOrReturnTypeConsumer ->
                retracedMethodArguments(element)
                    .flatMap(
                        argumentsConsumer -> {
                          RetraceFrameResult frameResult =
                              element.hasLineNumber()
                                  ? classResult.lookupFrame(
                                      element.getMethodName(), element.getLineNumber())
                                  : classResult.lookupFrame(element.getMethodName());
                          return frameResult.stream()
                              .flatMap(
                                  frameElement -> {
                                    List<RetraceStackTraceProxy<T, ST>> retracedProxies =
                                        new ArrayList<>();
                                    frameElement.visitFrames(
                                        (frame, index) -> {
                                          RetraceStackTraceProxyImpl.Builder<T, ST> proxy =
                                              RetraceStackTraceProxyImpl.builder(element)
                                                  .setRetracedClass(frame.getHolderClass())
                                                  .setRetracedMethod(frame)
                                                  .setAmbiguous(
                                                      frameResult.isAmbiguous() && index == 0)
                                                  .setTopFrame(index == 0);
                                          if (element.hasLineNumber()) {
                                            proxy.setLineNumber(
                                                frame.getOriginalPositionOrDefault(
                                                    element.getLineNumber()));
                                          }
                                          if (element.hasFileName()) {
                                            proxy.setSourceFile(
                                                frameElement
                                                    .retraceSourceFile(frame, element.getFileName())
                                                    .getFilename());
                                          }
                                          fieldOrReturnTypeConsumer.accept(proxy);
                                          argumentsConsumer.accept(proxy);
                                          retracedProxies.add(proxy.build());
                                        });
                                    return retracedProxies.stream();
                                  });
                        }));
  }

  private Stream<RetraceStackTraceProxy<T, ST>> retraceField(
      ST element, RetraceClassResult classResult) {
    return retraceFieldOrReturnType(element)
        .flatMap(
            fieldOrReturnTypeConsumer ->
                retracedMethodArguments(element)
                    .flatMap(
                        argumentsConsumer -> {
                          RetraceFieldResult retraceFieldResult =
                              classResult.lookupField(element.getFieldName());
                          return retraceFieldResult.stream()
                              .map(
                                  fieldElement -> {
                                    RetraceStackTraceProxyImpl.Builder<T, ST> proxy =
                                        RetraceStackTraceProxyImpl.builder(element)
                                            .setRetracedClass(
                                                fieldElement.getField().getHolderClass())
                                            .setRetracedField(fieldElement.getField())
                                            .setAmbiguous(retraceFieldResult.isAmbiguous())
                                            .setTopFrame(true);
                                    if (element.hasFileName()) {
                                      proxy.setSourceFile(
                                          fieldElement
                                              .retraceSourceFile(element.getFileName())
                                              .getFilename());
                                    }
                                    fieldOrReturnTypeConsumer.accept(proxy);
                                    argumentsConsumer.accept(proxy);
                                    return proxy.build();
                                  });
                        }));
  }

  private Stream<Consumer<RetraceStackTraceProxyImpl.Builder<T, ST>>> retraceFieldOrReturnType(
      ST element) {
    if (!element.hasFieldOrReturnType()) {
      return Stream.of(noEffect -> {});
    }
    String elementOrReturnType = element.getFieldOrReturnType();
    if (elementOrReturnType.equals("void")) {
      return Stream.of(
          proxy -> proxy.setRetracedFieldOrReturnType(RetracedTypeReferenceImpl.createVoid()));
    } else {
      TypeReference typeReference = Reference.typeFromTypeName(elementOrReturnType);
      RetraceTypeResult retraceTypeResult = retracer.retraceType(typeReference);
      return retraceTypeResult.stream()
          .map(
              type ->
                  (proxy -> {
                    proxy.setRetracedFieldOrReturnType(type.getType());
                    if (retraceTypeResult.isAmbiguous()) {
                      proxy.setAmbiguous(true);
                    }
                  }));
    }
  }

  private Stream<Consumer<RetraceStackTraceProxyImpl.Builder<T, ST>>> retracedMethodArguments(
      ST element) {
    if (!element.hasMethodArguments()) {
      return Stream.of(noEffect -> {});
    }
    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<>());
    Box<Boolean> isAmbiguous = new Box<>(false);
    List<List<RetracedTypeReference>> retracedArguments =
        ListUtils.fold(
            retracedResults,
            initial,
            (acc, retracedTypeResult) -> {
              if (retracedTypeResult.isAmbiguous()) {
                isAmbiguous.set(true);
              }
              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;
            });
    return retracedArguments.stream()
        .map(
            arguments ->
                proxy -> {
                  proxy.setRetracedMethodArguments(arguments);
                  if (isAmbiguous.get()) {
                    proxy.setAmbiguous(true);
                  }
                });
  }

  public static class RetraceStackTraceProxyImpl<T, ST extends StackTraceElementProxy<T, ST>>
      implements RetraceStackTraceProxy<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 RetraceStackTraceProxyImpl(
        ST originalItem,
        RetracedClassReference retracedClass,
        RetracedMethodReference retracedMethod,
        RetracedFieldReference retracedField,
        RetracedTypeReference fieldOrReturnType,
        List<RetracedTypeReference> methodArguments,
        String sourceFile,
        int lineNumber,
        boolean isAmbiguous,
        boolean isTopFrame) {
      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;
    }

    @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>> Builder<T, ST> builder(
        ST originalElement) {
      return new Builder<>(originalElement);
    }

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

    @Override
    public int compareTo(RetraceStackTraceProxy<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 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> setAmbiguous(boolean ambiguous) {
        this.isAmbiguous = ambiguous;
        return this;
      }

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

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