// 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.DexClass;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/** Class provides basic information about symbols related to Kotlin support. */
public final class Kotlin {

  // Simply "kotlin", but to avoid being renamed by Shadow.relocate in build.gradle.
  public static final String NAME = String.join("", ImmutableList.of("k", "o", "t", "l", "i", "n"));

  // Simply "Lkotlin/", but to avoid being renamed by Shadow.relocate in build.gradle.
  private static final String KOTLIN =
      String.join("", ImmutableList.of("L", "k", "o", "t", "l", "i", "n", "/"));

  static String addKotlinPrefix(String str) {
    return KOTLIN + str;
  }

  public final DexItemFactory factory;

  public final DexType kotlinAssertions;
  public final Functional functional;
  public final Intrinsics intrinsics;
  public final Metadata metadata;

  public static final class ClassClassifiers {

    public static final String arrayBinaryName = NAME + "/Array";
  }

  // Mappings from JVM types to Kotlin types (of type DexType)
  final Map<DexType, DexType> knownTypeConversion;

  public Kotlin(DexItemFactory factory) {
    this.factory = factory;

    this.kotlinAssertions = factory.createType(addKotlinPrefix("_Assertions;"));
    this.functional = new Functional();
    this.intrinsics = new Intrinsics();
    this.metadata = new Metadata();

    // See {@link org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite}
    this.knownTypeConversion =
        ImmutableMap.<DexType, DexType>builder()
            // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/index.html
            // Boxed primitives and arrays
            .put(factory.booleanType, factory.createType(addKotlinPrefix("Boolean;")))
            .put(factory.boxedBooleanType, factory.createType(addKotlinPrefix("Boolean;")))
            .put(factory.booleanArrayType, factory.createType(addKotlinPrefix("BooleanArray;")))
            .put(factory.byteType, factory.createType(addKotlinPrefix("Byte;")))
            .put(factory.byteArrayType, factory.createType(addKotlinPrefix("ByteArray;")))
            .put(factory.charType, factory.createType(addKotlinPrefix("Char;")))
            .put(factory.charArrayType, factory.createType(addKotlinPrefix("CharArray;")))
            .put(factory.shortType, factory.createType(addKotlinPrefix("Short;")))
            .put(factory.shortArrayType, factory.createType(addKotlinPrefix("ShortArray;")))
            .put(factory.intType, factory.createType(addKotlinPrefix("Int;")))
            .put(factory.boxedIntType, factory.createType(addKotlinPrefix("Int;")))
            .put(factory.intArrayType, factory.createType(addKotlinPrefix("IntArray;")))
            .put(factory.longType, factory.createType(addKotlinPrefix("Long;")))
            .put(factory.longArrayType, factory.createType(addKotlinPrefix("LongArray;")))
            .put(factory.floatType, factory.createType(addKotlinPrefix("Float;")))
            .put(factory.floatArrayType, factory.createType(addKotlinPrefix("FloatArray;")))
            .put(factory.doubleType, factory.createType(addKotlinPrefix("Double;")))
            .put(factory.doubleArrayType, factory.createType(addKotlinPrefix("DoubleArray;")))
            // Other intrinsics
            .put(factory.voidType, factory.createType(addKotlinPrefix("Unit;")))
            .put(factory.objectType, factory.createType(addKotlinPrefix("Any;")))
            .put(factory.boxedVoidType, factory.createType(addKotlinPrefix("Nothing;")))
            .put(factory.stringType, factory.createType(addKotlinPrefix("String;")))
            .put(factory.charSequenceType, factory.createType(addKotlinPrefix("CharSequence;")))
            .put(factory.throwableType, factory.createType(addKotlinPrefix("Throwable;")))
            .put(factory.cloneableType, factory.createType(addKotlinPrefix("Cloneable;")))
            .put(factory.boxedNumberType, factory.createType(addKotlinPrefix("Number;")))
            .put(factory.comparableType, factory.createType(addKotlinPrefix("Comparable;")))
            .put(factory.enumType, factory.createType(addKotlinPrefix("Enum;")))
            // Collections
            .put(factory.iteratorType, factory.createType(addKotlinPrefix("collections/Iterator;")))
            .put(
                factory.collectionType,
                factory.createType(addKotlinPrefix("collections/Collection;")))
            .put(factory.listType, factory.createType(addKotlinPrefix("collections/List;")))
            .put(factory.setType, factory.createType(addKotlinPrefix("collections/Set;")))
            .put(factory.mapType, factory.createType(addKotlinPrefix("collections/Map;")))
            .put(
                factory.listIteratorType,
                factory.createType(addKotlinPrefix("collections/ListIterator;")))
            .put(factory.iterableType, factory.createType(addKotlinPrefix("collections/Iterable;")))
            .put(
                factory.mapEntryType, factory.createType(addKotlinPrefix("collections/Map$Entry;")))
            // .../jvm/functions/FunctionN -> .../FunctionN
            .putAll(
                IntStream.rangeClosed(0, 22)
                    .boxed()
                    .collect(
                        Collectors.toMap(
                            i ->
                                factory.createType(
                                    addKotlinPrefix("jvm/functions/Function" + i + ";")),
                            i -> factory.createType(addKotlinPrefix("Function" + i + ";")))))
            .build();
  }

  public final class Functional {
    // NOTE: Kotlin stdlib defines interface Function0 till Function22 explicitly, see:
    //    https://github.com/JetBrains/kotlin/blob/master/libraries/
    //                    stdlib/jvm/runtime/kotlin/jvm/functions/Functions.kt
    //
    // For functions with arity bigger that 22 it is supposed to use FunctionN as described
    // in https://github.com/JetBrains/kotlin/blob/master/spec-docs/function-types.md,
    // but in current implementation (v1.2.21) defining such a lambda results in:
    //   > "Error: A JNI error has occurred, please check your installation and try again"
    //
    // This implementation just ignores lambdas with arity > 22.
    private final Object2IntMap<DexType> functions = new Object2IntArrayMap<>(
        IntStream.rangeClosed(0, 22).boxed().collect(
            Collectors.toMap(
                i -> factory.createType(addKotlinPrefix("jvm/functions/Function") + i + ";"),
                Function.identity()))
    );

    private Functional() {
    }

    public final DexString kotlinStyleLambdaInstanceName = factory.createString("INSTANCE");

    public final DexType functionBase =
        factory.createType(addKotlinPrefix("jvm/internal/FunctionBase;"));
    public final DexType lambdaType = factory.createType(addKotlinPrefix("jvm/internal/Lambda;"));

    public final DexMethod lambdaInitializerMethod = factory.createMethod(
        lambdaType,
        factory.createProto(factory.voidType, factory.intType),
        factory.constructorMethodName);

    public boolean isFunctionInterface(DexType type) {
      return functions.containsKey(type);
    }

    public int getArity(DexType type) {
      assert isFunctionInterface(type)
          : "Request to retrieve the arity from non-Kotlin-Function: " + type.toSourceString();
      return functions.getInt(type);
    }
  }

  public final class Metadata {
    public final DexType kotlinMetadataType = factory.createType(addKotlinPrefix("Metadata;"));
    public final DexString kind = factory.createString("k");
    public final DexString metadataVersion = factory.createString("mv");
    public final DexString bytecodeVersion = factory.createString("bv");
    public final DexString data1 = factory.createString("d1");
    public final DexString data2 = factory.createString("d2");
    public final DexString extraString = factory.createString("xs");
    public final DexString packageName = factory.createString("pn");
    public final DexString extraInt = factory.createString("xi");
  }

  // kotlin.jvm.internal.Intrinsics class
  public final class Intrinsics {
    public final DexType type = factory.createType(addKotlinPrefix("jvm/internal/Intrinsics;"));
    public final DexMethod throwParameterIsNullException = factory.createMethod(type,
        factory.createProto(factory.voidType, factory.stringType), "throwParameterIsNullException");
    public final DexMethod checkParameterIsNotNull = factory.createMethod(type,
        factory.createProto(factory.voidType, factory.objectType, factory.stringType),
        "checkParameterIsNotNull");
    public final DexMethod throwNpe = factory.createMethod(
        type, factory.createProto(factory.voidType), "throwNpe");
  }

  // Calculates kotlin info for a class.
  public KotlinInfo getKotlinInfo(DexClass clazz, DiagnosticsHandler reporter) {
    return KotlinClassMetadataReader.getKotlinInfo(this, clazz, reporter);
  }
}
