// 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 static com.android.tools.r8.retrace.internal.RetraceUtils.methodReferenceFromMappedRange;

import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRange;
import com.android.tools.r8.naming.Range;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.retrace.RetraceFrameResult;
import com.android.tools.r8.retrace.RetraceSourceFileResult;
import com.android.tools.r8.retrace.RetracedClassMember;
import com.android.tools.r8.retrace.RetracedMethod;
import com.android.tools.r8.retrace.Retracer;
import com.android.tools.r8.utils.Pair;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Stream;

public class RetraceFrameResultImpl implements RetraceFrameResult {

  private final RetraceClassResultImpl classResult;
  private final MethodDefinition methodDefinition;
  private final int obfuscatedPosition;
  private final List<Pair<RetraceClassResultImpl.ElementImpl, List<MappedRange>>> mappedRanges;
  private final Retracer retracer;

  public RetraceFrameResultImpl(
      RetraceClassResultImpl classResult,
      List<Pair<RetraceClassResultImpl.ElementImpl, List<MappedRange>>> mappedRanges,
      MethodDefinition methodDefinition,
      int obfuscatedPosition,
      Retracer retracer) {
    this.classResult = classResult;
    this.methodDefinition = methodDefinition;
    this.obfuscatedPosition = obfuscatedPosition;
    this.mappedRanges = mappedRanges;
    this.retracer = retracer;
  }

  @Override
  public boolean isAmbiguous() {
    if (mappedRanges.size() > 1) {
      return true;
    }
    List<MappedRange> methodRanges = mappedRanges.get(0).getSecond();
    if (methodRanges == null || methodRanges.isEmpty()) {
      return false;
    }
    MappedRange lastRange = methodRanges.get(0);
    for (MappedRange mappedRange : methodRanges) {
      if (mappedRange != lastRange
          && (mappedRange.minifiedRange == null
              || !mappedRange.minifiedRange.equals(lastRange.minifiedRange))) {
        return true;
      }
    }
    return false;
  }

  @Override
  public Stream<Element> stream() {
    return mappedRanges.stream()
        .flatMap(
            mappedRangePair -> {
              RetraceClassResultImpl.ElementImpl classElement = mappedRangePair.getFirst();
              List<MappedRange> mappedRanges = mappedRangePair.getSecond();
              if (mappedRanges == null || mappedRanges.isEmpty()) {
                return Stream.of(
                    new ElementImpl(
                        this,
                        classElement,
                        RetracedMethodImpl.create(
                            methodDefinition.substituteHolder(
                                classElement.getRetracedClass().getClassReference())),
                        ImmutableList.of(),
                        obfuscatedPosition));
              }
              // Iterate over mapped ranges that may have different positions than specified.
              List<ElementImpl> ambiguousFrames = new ArrayList<>();
              Range minifiedRange = mappedRanges.get(0).minifiedRange;
              List<MappedRange> mappedRangesForElement = Lists.newArrayList(mappedRanges.get(0));
              for (int i = 1; i < mappedRanges.size(); i++) {
                MappedRange mappedRange = mappedRanges.get(i);
                if (minifiedRange == null || !minifiedRange.equals(mappedRange.minifiedRange)) {
                  // This is a new frame
                  ambiguousFrames.add(
                      elementFromMappedRanges(mappedRangesForElement, classElement));
                  mappedRangesForElement = new ArrayList<>();
                }
                mappedRangesForElement.add(mappedRange);
              }
              ambiguousFrames.add(elementFromMappedRanges(mappedRangesForElement, classElement));
              return ambiguousFrames.stream();
            });
  }

  private ElementImpl elementFromMappedRanges(
      List<MappedRange> mappedRangesForElement, RetraceClassResultImpl.ElementImpl classElement) {
    MappedRange topFrame = mappedRangesForElement.get(0);
    MethodReference methodReference =
        methodReferenceFromMappedRange(
            topFrame, classElement.getRetracedClass().getClassReference());
    return new ElementImpl(
        this,
        classElement,
        getRetracedMethod(methodReference, topFrame, obfuscatedPosition),
        mappedRangesForElement,
        obfuscatedPosition);
  }

  private RetracedMethodImpl getRetracedMethod(
      MethodReference methodReference, MappedRange mappedRange, int obfuscatedPosition) {
    if (mappedRange.minifiedRange == null) {
      int originalLineNumber = mappedRange.getFirstLineNumberOfOriginalRange();
      return RetracedMethodImpl.create(
          methodReference, originalLineNumber > 0 ? originalLineNumber : obfuscatedPosition);
    }
    if (obfuscatedPosition == -1 || !mappedRange.minifiedRange.contains(obfuscatedPosition)) {
      return RetracedMethodImpl.create(methodReference);
    }
    return RetracedMethodImpl.create(
        methodReference, mappedRange.getOriginalLineNumber(obfuscatedPosition));
  }

  public static class ElementImpl implements RetraceFrameResult.Element {

    private final RetracedMethodImpl methodReference;
    private final RetraceFrameResultImpl retraceFrameResult;
    private final RetraceClassResultImpl.ElementImpl classElement;
    private final List<MappedRange> mappedRanges;
    private final int obfuscatedPosition;

    public ElementImpl(
        RetraceFrameResultImpl retraceFrameResult,
        RetraceClassResultImpl.ElementImpl classElement,
        RetracedMethodImpl methodReference,
        List<MappedRange> mappedRanges,
        int obfuscatedPosition) {
      this.methodReference = methodReference;
      this.retraceFrameResult = retraceFrameResult;
      this.classElement = classElement;
      this.mappedRanges = mappedRanges;
      this.obfuscatedPosition = obfuscatedPosition;
    }

    @Override
    public boolean isUnknown() {
      return methodReference.isUnknown();
    }

    @Override
    public RetracedMethodImpl getTopFrame() {
      return methodReference;
    }

    @Override
    public RetraceClassResultImpl.ElementImpl getClassElement() {
      return classElement;
    }

    @Override
    public void visitFrames(BiConsumer<RetracedMethod, Integer> consumer) {
      int counter = 0;
      consumer.accept(getTopFrame(), counter++);
      for (RetracedMethodImpl outerFrame : getOuterFrames()) {
        consumer.accept(outerFrame, counter++);
      }
    }

    @Override
    public RetraceSourceFileResult retraceSourceFile(RetracedClassMember frame, String sourceFile) {
      return RetraceUtils.getSourceFile(
          classElement, frame.getHolderClass(), sourceFile, retraceFrameResult.retracer);
    }

    @Override
    public List<RetracedMethodImpl> getOuterFrames() {
      if (mappedRanges == null) {
        return Collections.emptyList();
      }
      List<RetracedMethodImpl> outerFrames = new ArrayList<>();
      for (int i = 1; i < mappedRanges.size(); i++) {
        MappedRange mappedRange = mappedRanges.get(i);
        MethodReference methodReference =
            methodReferenceFromMappedRange(
                mappedRange, classElement.getRetracedClass().getClassReference());
        outerFrames.add(
            retraceFrameResult.getRetracedMethod(methodReference, mappedRange, obfuscatedPosition));
      }
      return outerFrames;
    }
  }
}
