// Copyright (c) 2022, 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.utils;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.IndexedDexItem;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.retrace.RetraceClassElement;
import com.android.tools.r8.retrace.RetraceElement;
import com.android.tools.r8.retrace.RetraceMethodResult;
import com.android.tools.r8.retrace.RetraceResult;
import com.android.tools.r8.retrace.RetracedFieldReference;
import com.android.tools.r8.retrace.RetracedFieldReference.KnownRetracedFieldReference;
import com.android.tools.r8.retrace.RetracedMethodReference;
import com.android.tools.r8.retrace.RetracedMethodReference.KnownRetracedMethodReference;
import com.android.tools.r8.retrace.Retracer;
import com.android.tools.r8.retrace.internal.MappingSupplierInternalImpl;
import com.android.tools.r8.retrace.internal.RetracerImpl;
import java.util.function.Function;

public class RetracerForCodePrinting {

  private static final RetracerForCodePrinting EMPTY = new RetracerForCodePrinting(null);

  public static RetracerForCodePrinting empty() {
    return EMPTY;
  }

  private final Retracer retracer;

  private RetracerForCodePrinting(Retracer retracer) {
    this.retracer = retracer;
  }

  public static RetracerForCodePrinting create(
      ClassNameMapper classNameMapper, DiagnosticsHandler handler) {
    return classNameMapper == null
        ? empty()
        : new RetracerForCodePrinting(
            RetracerImpl.createInternal(
                MappingSupplierInternalImpl.createInternal(classNameMapper), handler));
  }

  public <T extends RetraceElement<?>> String joinAmbiguousResults(
      RetraceResult<T> retraceResult, Function<T, String> nameToString) {
    return StringUtils.join(" <OR> ", retraceResult.stream(), nameToString);
  }

  private String typeToString(
      DexType type,
      Function<DexType, String> noRetraceString,
      Function<RetraceClassElement, String> retraceResult) {
    return retracer == null
        ? noRetraceString.apply(type)
        : joinAmbiguousResults(retracer.retraceClass(type.asClassReference()), retraceResult);
  }

  public String toSourceString(DexType type) {
    return typeToString(
        type, DexType::toSourceString, element -> element.getRetracedClass().getTypeName());
  }

  public String toDescriptor(DexType type) {
    return typeToString(
        type, DexType::toDescriptorString, element -> element.getRetracedClass().getDescriptor());
  }

  private String retraceMethodToString(
      DexMethod method,
      Function<DexMethod, String> noRetraceString,
      Function<KnownRetracedMethodReference, String> knownToString,
      Function<RetracedMethodReference, String> unknownToString) {
    if (retracer == null) {
      return noRetraceString.apply(method);
    }
    // TODO(b/169953605): Use retracer.retraceMethod() when we have enough information.
    MethodReference methodReference = method.asMethodReference();
    RetraceMethodResult retraceMethodResult =
        retracer
            .retraceClass(methodReference.getHolderClass())
            .lookupMethod(methodReference.getMethodName());
    return joinAmbiguousResults(
        retraceMethodResult,
        element -> {
          if (element.isUnknown()) {
            return unknownToString.apply(element.getRetracedMethod());
          } else {
            return knownToString.apply(element.getRetracedMethod().asKnown());
          }
        });
  }

  public String toSourceString(DexMethod method) {
    return retraceMethodToString(
        method,
        DexMethod::toSourceString,
        knownRetracedMethodReference ->
            knownRetracedMethodReference.getMethodReference().toSourceString(),
        unknown -> unknown.getHolderClass().getTypeName() + " " + unknown.getMethodName());
  }

  public String toDescriptor(DexMethod method) {
    return retraceMethodToString(
        method,
        m -> m.asMethodReference().toString(),
        knownRetracedMethodReference ->
            knownRetracedMethodReference.getMethodReference().toString(),
        unknown -> unknown.getHolderClass().getDescriptor() + unknown.getMethodName());
  }

  private String retraceFieldToString(
      DexField field,
      Function<DexField, String> noRetraceString,
      Function<KnownRetracedFieldReference, String> knownToString,
      Function<RetracedFieldReference, String> unknownToString) {
    if (retracer == null) {
      return noRetraceString.apply(field);
    }
    // TODO(b/169953605): Use retracer.retraceField() when we have enough information.
    FieldReference fieldReference = field.asFieldReference();
    return joinAmbiguousResults(
        retracer
            .retraceClass(fieldReference.getHolderClass())
            .lookupField(fieldReference.getFieldName()),
        element -> {
          if (element.isUnknown()) {
            return unknownToString.apply(element.getField());
          } else {
            return knownToString.apply(element.getField().asKnown());
          }
        });
  }

  public String toSourceString(DexField field) {
    return retraceFieldToString(
        field,
        f -> f.asFieldReference().toSourceString(),
        known -> known.getFieldReference().toSourceString(),
        unknown -> unknown.getHolderClass().getDescriptor() + " " + unknown.getFieldName());
  }

  public String toDescriptor(DexField field) {
    return retraceFieldToString(
        field,
        f -> f.asFieldReference().toString(),
        known -> known.getFieldReference().toString(),
        unknown -> unknown.getHolderClass().getDescriptor() + unknown.getFieldName());
  }

  public String toDescriptor(IndexedDexItem item) {
    if (!(item instanceof DexReference)) {
      return item.toString();
    }
    return ((DexReference) item).apply(this::toDescriptor, this::toDescriptor, this::toDescriptor);
  }

  public String toSourceString(IndexedDexItem item) {
    if (!(item instanceof DexReference)) {
      return item.toSourceString();
    }
    return ((DexReference) item)
        .apply(this::toSourceString, this::toSourceString, this::toSourceString);
  }

  public boolean isEmpty() {
    return this == EMPTY;
  }
}
