// Copyright (c) 2019, 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 com.android.tools.r8.Keep;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRange;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRangesOfName;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.Range;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.MethodReference.UnknownMethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.utils.DescriptorUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

@Keep
public class RetraceMethodResult extends Result<RetraceMethodResult.Element, RetraceMethodResult> {

  private final String obfuscatedName;
  private final RetraceClassResult.Element classElement;
  private final MappedRangesOfName mappedRanges;
  private final RetraceApi retracer;
  private Boolean isAmbiguousCached = null;

  RetraceMethodResult(
      RetraceClassResult.Element classElement,
      MappedRangesOfName mappedRanges,
      String obfuscatedName,
      RetraceApi retracer) {
    this.classElement = classElement;
    this.mappedRanges = mappedRanges;
    this.obfuscatedName = obfuscatedName;
    this.retracer = retracer;
    assert classElement != null;
  }

  public UnknownMethodReference getUnknownReference() {
    return new UnknownMethodReference(classElement.getClassReference(), obfuscatedName);
  }

  private boolean hasRetraceResult() {
    return mappedRanges != null && mappedRanges.getMappedRanges().size() > 0;
  }

  public boolean isAmbiguous() {
    if (isAmbiguousCached != null) {
      return isAmbiguousCached;
    }
    if (!hasRetraceResult()) {
      return false;
    }
    assert mappedRanges != null;
    Range minifiedRange = null;
    boolean seenNull = false;
    for (MappedRange mappedRange : mappedRanges.getMappedRanges()) {
      if (minifiedRange != null && !minifiedRange.equals(mappedRange.minifiedRange)) {
        isAmbiguousCached = true;
        return true;
      } else if (minifiedRange == null) {
        if (seenNull) {
          isAmbiguousCached = true;
          return true;
        }
        seenNull = true;
      }
      minifiedRange = mappedRange.minifiedRange;
    }
    isAmbiguousCached = false;
    return false;
  }

  public RetraceMethodResult narrowByLine(int linePosition) {
    if (!hasRetraceResult()) {
      return this;
    }
    List<MappedRange> narrowedRanges = this.mappedRanges.allRangesForLine(linePosition, false);
    if (narrowedRanges.isEmpty()) {
      narrowedRanges = new ArrayList<>();
      for (MappedRange mappedRange : this.mappedRanges.getMappedRanges()) {
        if (mappedRange.minifiedRange == null) {
          narrowedRanges.add(mappedRange);
        }
      }
    }
    return new RetraceMethodResult(
        classElement, new MappedRangesOfName(narrowedRanges), obfuscatedName, retracer);
  }

  @Override
  public Stream<Element> stream() {
    if (!hasRetraceResult()) {
      return Stream.of(new Element(this, classElement, getUnknownReference(), null));
    }
    return mappedRanges.getMappedRanges().stream()
        .map(
            mappedRange -> {
              MethodSignature signature = mappedRange.signature;
              ClassReference holder =
                  mappedRange.signature.isQualified()
                      ? Reference.classFromDescriptor(
                          DescriptorUtils.javaTypeToDescriptor(
                              mappedRange.signature.toHolderFromQualified()))
                      : classElement.getClassReference();
              List<TypeReference> formalTypes = new ArrayList<>(signature.parameters.length);
              for (String parameter : signature.parameters) {
                formalTypes.add(Reference.typeFromTypeName(parameter));
              }
              TypeReference returnType =
                  Reference.returnTypeFromDescriptor(
                      DescriptorUtils.javaTypeToDescriptor(signature.type));
              MethodReference retracedMethod =
                  Reference.method(
                      holder,
                      signature.isQualified() ? signature.toUnqualifiedName() : signature.name,
                      formalTypes,
                      returnType);
              return new Element(this, classElement, retracedMethod, mappedRange);
            });
  }

  @Override
  public RetraceMethodResult forEach(Consumer<Element> resultConsumer) {
    stream().forEach(resultConsumer);
    return this;
  }

  public static class Element {

    private final MethodReference methodReference;
    private final RetraceMethodResult retraceMethodResult;
    private final RetraceClassResult.Element classElement;
    private final MappedRange mappedRange;

    private Element(
        RetraceMethodResult retraceMethodResult,
        RetraceClassResult.Element classElement,
        MethodReference methodReference,
        MappedRange mappedRange) {
      this.classElement = classElement;
      this.retraceMethodResult = retraceMethodResult;
      this.methodReference = methodReference;
      this.mappedRange = mappedRange;
    }

    public MethodReference getMethodReference() {
      return methodReference;
    }

    public RetraceMethodResult getRetraceMethodResult() {
      return retraceMethodResult;
    }

    public RetraceClassResult.Element getClassElement() {
      return classElement;
    }

    public int getOriginalLineNumber(int linePosition) {
      return mappedRange != null ? mappedRange.getOriginalLineNumber(linePosition) : linePosition;
    }

    public boolean containsMinifiedLineNumber(int linePosition) {
      if (hasNoLineNumberRange()) {
        return false;
      }
      return mappedRange.minifiedRange.from <= linePosition
          && linePosition <= mappedRange.minifiedRange.to;
    }

    public boolean hasNoLineNumberRange() {
      return mappedRange == null || mappedRange.minifiedRange == null;
    }

    public int getFirstLineNumberOfOriginalRange() {
      if (hasNoLineNumberRange()) {
        return 0;
      }
      return mappedRange.getFirstLineNumberOfOriginalRange();
    }

    public RetraceSourceFileResult retraceSourceFile(String sourceFile) {
      return RetraceUtils.getSourceFile(
          classElement, methodReference.getHolderClass(), sourceFile, retraceMethodResult.retracer);
    }
  }
}
