// 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.kotlin.Kotlin.NAME;
import static com.android.tools.r8.utils.DescriptorUtils.descriptorToKotlinClassifier;
import static kotlinx.metadata.FlagsKt.flagsOf;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GenericSignature.ArrayTypeSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
import com.android.tools.r8.graph.GenericSignature.TypeVariableSignature;
import com.android.tools.r8.kotlin.Kotlin.ClassClassifiers;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import kotlinx.metadata.KmTypeParameter;
import kotlinx.metadata.KmTypeVisitor;
import kotlinx.metadata.KmVariance;

class KotlinMetadataSynthesizerUtils {

  // The KmVisitorOption is used for star projections, otherwise we will have late-init failures
  // due to visitStarProjection adding an argument.
  enum KmVisitorOption {
    VISIT_NEW,
    VISIT_PARENT
  }

  // The AddKotlinAnyType is carrying around information regarding the need for adding the trivial
  // type Kotlin/Any. The information is not consistently added, for example, for upper bounds
  // the trivial bound is not recorded.
  public enum AddKotlinAnyType {
    ADD,
    DISREGARD
  }

  static void populateKmTypeFromSignature(
      FieldTypeSignature typeSignature,
      KotlinTypeInfo originalTypeInfo,
      Function<KmVisitorOption, KmTypeVisitor> typeVisitor,
      List<KmTypeParameter> allTypeParameters,
      DexItemFactory factory,
      AddKotlinAnyType addAny) {
    if (typeSignature.isClassTypeSignature()) {
      populateKmTypeFromClassTypeSignature(
          typeSignature.asClassTypeSignature(),
          originalTypeInfo,
          typeVisitor,
          allTypeParameters,
          factory,
          addAny);
    } else if (typeSignature.isArrayTypeSignature()) {
      populateKmTypeFromArrayTypeSignature(
          typeSignature.asArrayTypeSignature(),
          originalTypeInfo,
          typeVisitor,
          allTypeParameters,
          factory,
          addAny);
    } else if (typeSignature.isTypeVariableSignature()) {
      populateKmTypeFromTypeVariableSignature(
          typeSignature.asTypeVariableSignature(), typeVisitor, allTypeParameters);
    } else {
      assert typeSignature.isStar();
      typeVisitor.apply(KmVisitorOption.VISIT_PARENT).visitStarProjection();
    }
  }

  private static void populateKmTypeFromTypeVariableSignature(
      TypeVariableSignature typeSignature,
      Function<KmVisitorOption, KmTypeVisitor> typeVisitor,
      List<KmTypeParameter> allTypeParameters) {
    for (KmTypeParameter typeParameter : allTypeParameters) {
      if (typeParameter
          .getName()
          .equals(typeSignature.asTypeVariableSignature().getTypeVariable())) {
        typeVisitor.apply(KmVisitorOption.VISIT_NEW).visitTypeParameter(typeParameter.getId());
        return;
      }
    }
  }

  private static void populateKmTypeFromArrayTypeSignature(
      ArrayTypeSignature typeSignature,
      KotlinTypeInfo originalTypeInfo,
      Function<KmVisitorOption, KmTypeVisitor> typeVisitor,
      List<KmTypeParameter> allTypeParameters,
      DexItemFactory factory,
      AddKotlinAnyType addAny) {
    ArrayTypeSignature arrayTypeSignature = typeSignature.asArrayTypeSignature();
    if (!arrayTypeSignature.elementSignature().isFieldTypeSignature()) {
      return;
    }
    KmTypeVisitor kmType = typeVisitor.apply(KmVisitorOption.VISIT_NEW);
    kmType.visitClass(ClassClassifiers.arrayBinaryName);
    KotlinTypeProjectionInfo projectionInfo =
        originalTypeInfo == null ? null : originalTypeInfo.getArgumentOrNull(0);
    populateKmTypeFromSignature(
        arrayTypeSignature.elementSignature().asFieldTypeSignature(),
        projectionInfo == null ? null : projectionInfo.typeInfo,
        (kmVisitorOption) -> {
          if (kmVisitorOption == KmVisitorOption.VISIT_PARENT) {
            assert originalTypeInfo.getArguments().size() == 1
                && originalTypeInfo.getArguments().get(0).isStarProjection();
            return kmType;
          } else {
            // TODO(b/152886451): Variance is only NULL when star projection. If that is the case
            //  we should just apply starProjection.
            return kmType.visitArgument(
                flagsOf(),
                projectionInfo == null || projectionInfo.variance == null
                    ? KmVariance.INVARIANT
                    : projectionInfo.variance);
          }
        },
        allTypeParameters,
        factory,
        addAny);
  }

  private static void populateKmTypeFromClassTypeSignature(
      ClassTypeSignature typeSignature,
      KotlinTypeInfo originalTypeInfo,
      Function<KmVisitorOption, KmTypeVisitor> typeVisitor,
      List<KmTypeParameter> allTypeParameters,
      DexItemFactory factory,
      AddKotlinAnyType addAny) {
    // No need to record the trivial argument.
    if (addAny == AddKotlinAnyType.DISREGARD && factory.objectType == typeSignature.type()) {
      return;
    }
    KmTypeVisitor kmType = typeVisitor.apply(KmVisitorOption.VISIT_NEW);
    kmType.visitClass(toClassifier(typeSignature.type(), factory));
    for (int i = 0; i < typeSignature.typeArguments().size(); i++) {
      FieldTypeSignature typeArgument = typeSignature.typeArguments().get(i);
      KotlinTypeProjectionInfo projectionInfo =
          originalTypeInfo == null ? null : originalTypeInfo.getArgumentOrNull(i);
      populateKmTypeFromSignature(
          typeArgument,
          projectionInfo == null ? null : projectionInfo.typeInfo,
          (kmVisitorOption) -> {
            if (kmVisitorOption == KmVisitorOption.VISIT_PARENT) {
              assert projectionInfo == null || projectionInfo.isStarProjection();
              return kmType;
            } else {
              // TODO(b/152886451): Variance is only NULL when star projection. If that is the case
              //  we should just apply starProjection.
              return kmType.visitArgument(
                  flagsOf(),
                  projectionInfo == null || projectionInfo.variance == null
                      ? KmVariance.INVARIANT
                      : projectionInfo.variance);
            }
          },
          allTypeParameters,
          factory,
          addAny);
    }
  }

  static String toClassifier(DexType type, DexItemFactory factory) {
    // E.g., V -> kotlin/Unit, J -> kotlin/Long, [J -> kotlin/LongArray
    if (factory.kotlin.knownTypeConversion.containsKey(type)) {
      DexType convertedType = factory.kotlin.knownTypeConversion.get(type);
      assert convertedType != null;
      return descriptorToKotlinClassifier(convertedType.toDescriptorString());
    }
    // E.g., [Ljava/lang/String; -> kotlin/Array
    if (type.isArrayType()) {
      return NAME + "/Array";
    }
    return descriptorToKotlinClassifier(type.toDescriptorString());
  }

  /**
   * Utility method building up all type-parameters from {@code classTypeParameters} combined with
   * {@code parameters}, where the consumer {@code addedFromParameters} is called for every
   * conversion of {@Code FormalTypeParameter} to {@Code KmTypeParameter}.
   *
   * <pre>
   *  classTypeParameters: [KmTypeParameter(T), KmTypeParameter(S)]
   *  parameters: [FormalTypeParameter(R)]
   *  result: [KmTypeParameter(T), KmTypeParameter(S), KmTypeParameter(R)].
   * </pre>
   *
   * @param classTypeParameters
   * @param originalTypeParameterInfo
   * @param parameters
   * @param factory
   * @param addedFromParameters
   * @return
   */
  static List<KmTypeParameter> convertFormalTypeParameters(
      List<KmTypeParameter> classTypeParameters,
      List<KotlinTypeParameterInfo> originalTypeParameterInfo,
      List<FormalTypeParameter> parameters,
      DexItemFactory factory,
      Consumer<KmTypeParameter> addedFromParameters) {
    if (parameters.isEmpty()) {
      return classTypeParameters;
    }
    ImmutableList.Builder<KmTypeParameter> builder = ImmutableList.builder();
    builder.addAll(classTypeParameters);
    // Assign type-variables ids to names. All generic signatures has been minified at this point,
    // but it may be that type-variables are used before we can see them (is that allowed?).
    for (int i = 0; i < parameters.size(); i++) {
      FormalTypeParameter parameter = parameters.get(i);
      int flags =
          originalTypeParameterInfo.size() > i
              ? originalTypeParameterInfo.get(i).getFlags()
              : flagsOf();
      KmVariance variance =
          originalTypeParameterInfo.size() > i
              ? originalTypeParameterInfo.get(i).getVariance()
              : KmVariance.INVARIANT;
      KmTypeParameter element =
          new KmTypeParameter(
              flags,
              parameter.getName(),
              getNewId(originalTypeParameterInfo, parameter.getName(), i),
              variance);
      builder.add(element);
      addedFromParameters.accept(element);
    }
    ImmutableList<KmTypeParameter> allTypeParameters = builder.build();
    for (int i = 0; i < parameters.size(); i++) {
      FormalTypeParameter parameter = parameters.get(i);
      KmTypeParameter kmTypeParameter = allTypeParameters.get(classTypeParameters.size() + i);
      visitUpperBound(parameter.getClassBound(), allTypeParameters, kmTypeParameter, factory);
      if (parameter.getInterfaceBounds() != null) {
        for (FieldTypeSignature interfaceBound : parameter.getInterfaceBounds()) {
          visitUpperBound(interfaceBound, allTypeParameters, kmTypeParameter, factory);
        }
      }
    }
    return allTypeParameters;
  }

  // Tries to pick the id from the type-parameter name. If no such exist, compute the highest id and
  // add the index of the current argument (to ensure unique naming in sequence).
  private static int getNewId(
      List<KotlinTypeParameterInfo> typeParameterInfos, String typeVariable, int currentId) {
    int maxId = -1;
    for (KotlinTypeParameterInfo typeParameterInfo : typeParameterInfos) {
      if (typeParameterInfo.getName().equals(typeVariable)) {
        return typeParameterInfo.getId();
      }
      maxId = Math.max(maxId, typeParameterInfo.getId());
    }
    return maxId + 1 + currentId;
  }

  private static void visitUpperBound(
      FieldTypeSignature typeSignature,
      List<KmTypeParameter> allTypeParameters,
      KmTypeParameter parameter,
      DexItemFactory factory) {
    if (typeSignature.isUnknown()) {
      return;
    }
    populateKmTypeFromSignature(
        typeSignature,
        null,
        (kmVisitorOption) -> {
          assert kmVisitorOption == KmVisitorOption.VISIT_NEW;
          return parameter.visitUpperBound(flagsOf());
        },
        allTypeParameters,
        factory,
        AddKotlinAnyType.DISREGARD);
  }
}
