// Copyright (c) 2018, 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 com.android.tools.r8.DiagnosticsHandler;
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.DexEncodedAnnotation;
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.graph.DexValue.DexValueString;
import com.android.tools.r8.utils.StringDiagnostic;
import java.util.IdentityHashMap;
import java.util.Map;
import kotlinx.metadata.InconsistentKotlinMetadataException;
import kotlinx.metadata.jvm.KotlinClassHeader;
import kotlinx.metadata.jvm.KotlinClassMetadata;

final class KotlinClassMetadataReader {

  static KotlinInfo getKotlinInfo(
      Kotlin kotlin,
      DexClass clazz,
      DiagnosticsHandler reporter) {
    DexAnnotation meta = clazz.annotations().getFirstMatching(kotlin.metadata.kotlinMetadataType);
    if (meta != null) {
      try {
        return createKotlinInfo(kotlin, clazz, meta.annotation);
      } catch (ClassCastException | InconsistentKotlinMetadataException | MetadataError e) {
        reporter.info(
            new StringDiagnostic("Class " + clazz.type.toSourceString()
                + " has malformed kotlin.Metadata: " + e.getMessage()));
      } catch (Throwable e) {
        reporter.info(
            new StringDiagnostic("Unexpected error while reading " + clazz.type.toSourceString()
                + "'s kotlin.Metadata: " + e.getMessage()));
      }
    }
    return null;
  }

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

    DexAnnotationElement kind = elementMap.get(kotlin.metadata.kind);
    if (kind == null) {
      throw new MetadataError("element 'k' is missing.");
    }
    Integer k = (Integer) kind.value.getBoxedValue();
    DexAnnotationElement metadataVersion = elementMap.get(kotlin.metadata.metadataVersion);
    int[] mv = metadataVersion == null ? null : getUnboxedIntArray(metadataVersion.value, "mv");
    DexAnnotationElement bytecodeVersion = elementMap.get(kotlin.metadata.bytecodeVersion);
    int[] bv = bytecodeVersion == null ? null : getUnboxedIntArray(bytecodeVersion.value, "bv");
    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();

    KotlinClassHeader header = new KotlinClassHeader(k, mv, bv, d1, d2, xs, pn, xi);
    return KotlinClassMetadata.read(header);
  }

  private static KotlinInfo createKotlinInfo(
      Kotlin kotlin, DexClass clazz, DexEncodedAnnotation metadataAnnotation) {
    KotlinClassMetadata kMetadata = toKotlinClassMetadata(kotlin, metadataAnnotation);

    if (kMetadata instanceof KotlinClassMetadata.Class) {
      return KotlinClass.fromKotlinClassMetadata(kMetadata, clazz);
    } else if (kMetadata instanceof KotlinClassMetadata.FileFacade) {
      // e.g., B.kt becomes class `BKt`
      return KotlinFile.fromKotlinClassMetadata(kMetadata, clazz);
    } else if (kMetadata instanceof KotlinClassMetadata.MultiFileClassFacade) {
      // multi-file class with the same @JvmName.
      return KotlinClassFacade.fromKotlinClassMetadata(kMetadata, clazz);
    } else if (kMetadata instanceof KotlinClassMetadata.MultiFileClassPart) {
      // A single file, which is part of multi-file class.
      return KotlinClassPart.fromKotlinClassMetadata(kMetadata, clazz);
    } else if (kMetadata instanceof KotlinClassMetadata.SyntheticClass) {
      return KotlinSyntheticClass.fromKotlinClassMetadata(kMetadata, kotlin, clazz);
    } else {
      throw new MetadataError("unsupported 'k' value: " + kMetadata.getHeader().getKind());
    }
  }

  private static int[] getUnboxedIntArray(DexValue v, String elementName) {
    if (!(v instanceof DexValueArray)) {
      throw new MetadataError("invalid '" + elementName + "' value: " + v.toSourceString());
    }
    DexValueArray intArrayValue = (DexValueArray) v;
    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 instanceof DexValueArray)) {
      throw new MetadataError("invalid '" + elementName + "' value: " + v.toSourceString());
    }
    DexValueArray stringArrayValue = (DexValueArray) v;
    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 instanceof DexValueString)) {
      throw new MetadataError("invalid '" + elementName + "' value: " + v.toSourceString());
    }
    return ((DexValueString) v).getValue().toString();
  }

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