// 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.KotlinMetadataUtils.getNoKotlinInfo;
import static com.android.tools.r8.kotlin.KotlinSyntheticClassInfo.getFlavour;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedAnnotation;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.kotlin.KotlinSyntheticClassInfo.Flavour;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.Consumer;
import kotlinx.metadata.InconsistentKotlinMetadataException;
import kotlinx.metadata.jvm.KotlinClassHeader;
import kotlinx.metadata.jvm.KotlinClassMetadata;
import kotlinx.metadata.jvm.KotlinClassMetadata.FileFacade;
import kotlinx.metadata.jvm.KotlinClassMetadata.MultiFileClassFacade;
import kotlinx.metadata.jvm.KotlinClassMetadata.MultiFileClassPart;
import kotlinx.metadata.jvm.KotlinClassMetadata.SyntheticClass;

public final class KotlinClassMetadataReader {

  private static final int SYNTHETIC_CLASS_KIND = 3;

  public static KotlinClassLevelInfo getKotlinInfo(
      DexClass clazz, AppView<?> appView, Consumer<DexEncodedMethod> keepByteCode)
      throws KotlinMetadataException {
    DexAnnotation meta =
        clazz.annotations().getFirstMatching(appView.dexItemFactory().kotlinMetadataType);
    return meta != null ? getKotlinInfo(clazz, appView, keepByteCode, meta) : getNoKotlinInfo();
  }

  public static KotlinClassLevelInfo getKotlinInfo(
      DexClass clazz,
      AppView<?> appView,
      Consumer<DexEncodedMethod> keepByteCode,
      DexAnnotation annotation)
      throws KotlinMetadataException {
    Kotlin kotlin = appView.dexItemFactory().kotlin;
    KotlinClassMetadata kMetadata = toKotlinClassMetadata(kotlin, annotation.annotation);
    if (kMetadata == null) {
      throw new KotlinMetadataException();
    }
    return createKotlinInfo(kotlin, clazz, kMetadata, appView, keepByteCode);
  }

  public static boolean isLambda(AppView<?> appView, DexClass clazz)
      throws KotlinMetadataException {
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    Kotlin kotlin = dexItemFactory.kotlin;
    Flavour flavour = getFlavour(clazz, kotlin);
    if (flavour == Flavour.Unclassified) {
      return false;
    }
    DexAnnotation metadataAnnotation =
        clazz.annotations().getFirstMatching(dexItemFactory.kotlinMetadataType);
    if (metadataAnnotation == null) {
      return false;
    }
    Map<DexString, DexAnnotationElement> elementMap = toElementMap(metadataAnnotation.annotation);
    if (getKind(kotlin, elementMap) == SYNTHETIC_CLASS_KIND) {
      KotlinClassMetadata kMetadata = toKotlinClassMetadata(kotlin, elementMap);
      if (kMetadata instanceof SyntheticClass) {
        return ((SyntheticClass) kMetadata).isLambda();
      }
    }
    assert toKotlinClassMetadata(kotlin, elementMap) instanceof SyntheticClass
            == (getKind(kotlin, elementMap) == SYNTHETIC_CLASS_KIND)
        : "Synthetic class kinds should agree";
    return false;
  }

  public static boolean hasKotlinClassMetadataAnnotation(
      DexClass clazz, DexDefinitionSupplier definitionSupplier) {
    return clazz
            .annotations()
            .getFirstMatching(definitionSupplier.dexItemFactory().kotlinMetadataType)
        != null;
  }

  public static KotlinClassMetadata toKotlinClassMetadata(
      Kotlin kotlin, DexEncodedAnnotation metadataAnnotation) throws KotlinMetadataException {
    return toKotlinClassMetadata(kotlin, toElementMap(metadataAnnotation));
  }

  private static Map<DexString, DexAnnotationElement> toElementMap(
      DexEncodedAnnotation metadataAnnotation) {
    Map<DexString, DexAnnotationElement> elementMap = new IdentityHashMap<>();
    for (DexAnnotationElement element : metadataAnnotation.elements) {
      elementMap.put(element.name, element);
    }
    return elementMap;
  }

  private static KotlinClassMetadata toKotlinClassMetadata(
      Kotlin kotlin, Map<DexString, DexAnnotationElement> elementMap)
      throws KotlinMetadataException {
    int k = getKind(kotlin, elementMap);
    DexAnnotationElement metadataVersion = elementMap.get(kotlin.metadata.metadataVersion);
    int[] mv = metadataVersion == null ? null : getUnboxedIntArray(metadataVersion.value, "mv");
    DexAnnotationElement data1 = elementMap.get(kotlin.metadata.data1);
    String[] d1 = data1 == null ? null : getUnboxedStringArray(data1.value, "d1");
    DexAnnotationElement data2 = elementMap.get(kotlin.metadata.data2);
    String[] d2 = data2 == null ? null : getUnboxedStringArray(data2.value, "d2");
    DexAnnotationElement extraString = elementMap.get(kotlin.metadata.extraString);
    String xs = extraString == null ? null : getUnboxedString(extraString.value, "xs");
    DexAnnotationElement packageName = elementMap.get(kotlin.metadata.packageName);
    String pn = packageName == null ? null : getUnboxedString(packageName.value, "pn");
    DexAnnotationElement extraInt = elementMap.get(kotlin.metadata.extraInt);
    Integer xi = extraInt == null ? null : (Integer) extraInt.value.getBoxedValue();

    try {
      KotlinClassHeader header = new KotlinClassHeader(k, mv, d1, d2, xs, pn, xi);
      return KotlinClassMetadata.read(header);
    } catch (ClassCastException | InconsistentKotlinMetadataException | MetadataError e) {
      throw new KotlinMetadataException(e);
    }
  }

  private static int getKind(Kotlin kotlin, Map<DexString, DexAnnotationElement> elementMap) {
    DexAnnotationElement kind = elementMap.get(kotlin.metadata.kind);
    if (kind == null) {
      throw new MetadataError("element 'k' is missing.");
    }
    return (Integer) kind.value.getBoxedValue();
  }

  public static KotlinClassLevelInfo createKotlinInfo(
      Kotlin kotlin,
      DexClass clazz,
      KotlinClassMetadata kMetadata,
      AppView<?> appView,
      Consumer<DexEncodedMethod> keepByteCode) {
    String packageName = kMetadata.getHeader().getPackageName();
    int[] metadataVersion = kMetadata.getHeader().getMetadataVersion();
    if (kMetadata instanceof KotlinClassMetadata.Class) {
      return KotlinClassInfo.create(
          (KotlinClassMetadata.Class) kMetadata,
          packageName,
          metadataVersion,
          clazz,
          appView,
          keepByteCode);
    } else if (kMetadata instanceof KotlinClassMetadata.FileFacade) {
      // e.g., B.kt becomes class `BKt`
      return KotlinFileFacadeInfo.create(
          (FileFacade) kMetadata, packageName, metadataVersion, clazz, appView, keepByteCode);
    } else if (kMetadata instanceof KotlinClassMetadata.MultiFileClassFacade) {
      // multi-file class with the same @JvmName.
      return KotlinMultiFileClassFacadeInfo.create(
          (MultiFileClassFacade) kMetadata, packageName, metadataVersion, appView.dexItemFactory());
    } else if (kMetadata instanceof KotlinClassMetadata.MultiFileClassPart) {
      // A single file, which is part of multi-file class.
      return KotlinMultiFileClassPartInfo.create(
          (MultiFileClassPart) kMetadata,
          packageName,
          metadataVersion,
          clazz,
          appView,
          keepByteCode);
    } else if (kMetadata instanceof KotlinClassMetadata.SyntheticClass) {
      return KotlinSyntheticClassInfo.create(
          (KotlinClassMetadata.SyntheticClass) kMetadata,
          packageName,
          metadataVersion,
          clazz,
          kotlin,
          appView);
    } else {
      throw new MetadataError("unsupported 'k' value: " + kMetadata.getHeader().getKind());
    }
  }

  private static int[] getUnboxedIntArray(DexValue v, String elementName) {
    if (!v.isDexValueArray()) {
      throw new MetadataError("invalid '" + elementName + "' value: " + v.toSourceString());
    }
    DexValueArray intArrayValue = v.asDexValueArray();
    DexValue[] values = intArrayValue.getValues();
    int[] result = new int [values.length];
    for (int i = 0; i < values.length; i++) {
      result[i] = (Integer) values[i].getBoxedValue();
    }
    return result;
  }

  private static String[] getUnboxedStringArray(DexValue v, String elementName) {
    if (!v.isDexValueArray()) {
      throw new MetadataError("invalid '" + elementName + "' value: " + v.toSourceString());
    }
    DexValueArray stringArrayValue = v.asDexValueArray();
    DexValue[] values = stringArrayValue.getValues();
    String[] result = new String [values.length];
    for (int i = 0; i < values.length; i++) {
      result[i] = getUnboxedString(values[i], elementName + "[" + i + "]");
    }
    return result;
  }

  private static String getUnboxedString(DexValue v, String elementName) {
    if (!v.isDexValueString()) {
      throw new MetadataError("invalid '" + elementName + "' value: " + v.toSourceString());
    }
    return v.asDexValueString().getValue().toString();
  }

  public static class MetadataError extends RuntimeException {
    private MetadataError(String cause) {
      super(cause);
    }
  }
}
