// 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.kotlin;

import static com.android.tools.r8.utils.FunctionUtils.forEachApply;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.function.Consumer;
import kotlinx.metadata.jvm.JvmMethodSignature;

/**
 * The JvmSignature for a method or property does not always correspond to the actual signature, see
 * b/154201250. We therefore need to model the signature as well.
 */
public class KotlinJvmMethodSignatureInfo implements EnqueuerMetadataTraceable {

  private static final List<KotlinTypeReference> EMPTY_PARAMETERS_LIST = ImmutableList.of();

  private final String name;
  private final KotlinTypeReference returnType;
  private final List<KotlinTypeReference> parameters;
  private final String invalidDescriptor;

  private KotlinJvmMethodSignatureInfo(
      String name, KotlinTypeReference returnType, List<KotlinTypeReference> parameters) {
    this.name = name;
    this.returnType = returnType;
    this.parameters = parameters;
    this.invalidDescriptor = null;
  }

  private KotlinJvmMethodSignatureInfo(String name, String invalidDescriptor) {
    this.name = name;
    this.invalidDescriptor = invalidDescriptor;
    this.parameters = EMPTY_PARAMETERS_LIST;
    this.returnType = null;
  }

  public static KotlinJvmMethodSignatureInfo create(
      JvmMethodSignature methodSignature, DexItemFactory factory) {
    if (methodSignature == null) {
      return null;
    }
    String name = methodSignature.getName();
    String descriptor = methodSignature.getDesc();
    if (!KotlinMetadataUtils.isValidMethodDescriptor(descriptor)) {
      // If the method descriptor is invalid, keep it as invalid.
      return new KotlinJvmMethodSignatureInfo(methodSignature.getName(), descriptor);
    }
    String returnTypeDescriptor = DescriptorUtils.getReturnTypeDescriptor(descriptor);
    KotlinTypeReference returnType =
        KotlinTypeReference.fromDescriptor(returnTypeDescriptor, factory);
    String[] descriptors = DescriptorUtils.getArgumentTypeDescriptors(descriptor);
    if (descriptors.length == 0) {
      return new KotlinJvmMethodSignatureInfo(name, returnType, EMPTY_PARAMETERS_LIST);
    }
    ImmutableList.Builder<KotlinTypeReference> parameters = ImmutableList.builder();
    for (String paramDescriptor : descriptors) {
      parameters.add(KotlinTypeReference.fromDescriptor(paramDescriptor, factory));
    }
    return new KotlinJvmMethodSignatureInfo(name, returnType, parameters.build());
  }

  boolean rewrite(
      Consumer<JvmMethodSignature> consumer,
      DexEncodedMethod method,
      AppView<?> appView,
      NamingLens namingLens) {
    if (invalidDescriptor != null) {
      consumer.accept(new JvmMethodSignature(name, invalidDescriptor));
      return false;
    }
    assert returnType != null;
    String finalName = name;
    boolean rewritten = false;
    if (method != null) {
      String methodName = method.getReference().name.toString();
      String rewrittenName = namingLens.lookupName(method.getReference()).toString();
      if (!methodName.equals(rewrittenName)) {
        finalName = rewrittenName;
        rewritten = true;
      }
    }
    StringBuilder descBuilder = new StringBuilder();
    descBuilder.append("(");
    String defValue = appView.dexItemFactory().objectType.toDescriptorString();
    for (KotlinTypeReference parameter : parameters) {
      rewritten |=
          parameter.toRenamedDescriptorOrDefault(
              descBuilder::append, appView, namingLens, defValue);
    }
    descBuilder.append(")");
    rewritten |=
        returnType.toRenamedDescriptorOrDefault(descBuilder::append, appView, namingLens, defValue);
    consumer.accept(new JvmMethodSignature(finalName, descBuilder.toString()));
    return rewritten;
  }

  @Override
  public String toString() {
    if (invalidDescriptor != null) {
      return name + "(" + invalidDescriptor + ")";
    }
    assert returnType != null;
    StringBuilder descBuilder = new StringBuilder();
    descBuilder.append(name);
    descBuilder.append("(");
    for (KotlinTypeReference parameter : parameters) {
      descBuilder.append(parameter.toString());
    }
    descBuilder.append(")");
    descBuilder.append(returnType.toString());
    return descBuilder.toString();
  }

  @Override
  public void trace(DexDefinitionSupplier definitionSupplier) {
    if (invalidDescriptor != null) {
      return;
    }
    assert returnType != null;
    returnType.trace(definitionSupplier);
    forEachApply(parameters, param -> param::trace, definitionSupplier);
  }
}
