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

import com.android.tools.r8.errors.InvalidDescriptorException;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import kotlinx.metadata.KmConstructor;
import kotlinx.metadata.KmConstructorExtensionVisitor;
import kotlinx.metadata.KmConstructorVisitor;
import kotlinx.metadata.KmExtensionType;
import kotlinx.metadata.KmFunction;
import kotlinx.metadata.KmFunctionExtensionVisitor;
import kotlinx.metadata.KmFunctionVisitor;
import kotlinx.metadata.KmProperty;
import kotlinx.metadata.KmPropertyExtensionVisitor;
import kotlinx.metadata.KmPropertyVisitor;
import kotlinx.metadata.jvm.JvmConstructorExtensionVisitor;
import kotlinx.metadata.jvm.JvmFieldSignature;
import kotlinx.metadata.jvm.JvmFunctionExtensionVisitor;
import kotlinx.metadata.jvm.JvmMethodSignature;
import kotlinx.metadata.jvm.JvmPropertyExtensionVisitor;

class KotlinMetadataJvmExtensionUtils {

  // Mappings from Kotlin types to JVM types (of String)
  private static final Map<String, String> knownTypeConversion =
      // See {@link org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite}
      ImmutableMap.<String, String>builder()
          // Boxed primitives and arrays
          .put(addKotlinPrefix("Boolean;"), "Z")
          .put(addKotlinPrefix("BooleanArray;"), "[Z")
          .put(addKotlinPrefix("Byte;"), "B")
          .put(addKotlinPrefix("ByteArray;"), "[B")
          .put(addKotlinPrefix("Char;"), "C")
          .put(addKotlinPrefix("CharArray;"), "[C")
          .put(addKotlinPrefix("Short;"), "S")
          .put(addKotlinPrefix("ShortArray;"), "[S")
          .put(addKotlinPrefix("Int;"), "I")
          .put(addKotlinPrefix("IntArray;"), "[I")
          .put(addKotlinPrefix("Long;"), "J")
          .put(addKotlinPrefix("LongArray;"), "[J")
          .put(addKotlinPrefix("Float;"), "F")
          .put(addKotlinPrefix("FloatArray;"), "[F")
          .put(addKotlinPrefix("Double;"), "D")
          .put(addKotlinPrefix("DoubleArray;"), "[D")
          // Other intrinsics
          .put(addKotlinPrefix("Unit;"), "V")
          .put(addKotlinPrefix("Any;"), "Ljava/lang/Object;")
          .put(addKotlinPrefix("Nothing;"), "Ljava/lang/Void;")
          .putAll(ImmutableList.of(
              "String", "CharSequence", "Throwable", "Cloneable", "Number", "Comparable", "Enum")
                  .stream().collect(Collectors.toMap(
                      t -> addKotlinPrefix(t + ";"),
                      t -> "Ljava/lang/" + t + ";")))
          // Collections
          .putAll(ImmutableList.of("Iterator", "Collection", "List", "Set", "Map", "ListIterator")
              .stream().collect(Collectors.toMap(
                  t -> addKotlinPrefix("collections/" + t + ";"),
                  t -> "Ljava/util/" + t + ";")))
          .putAll(ImmutableList.of("Iterator", "Collection", "List", "Set", "Map", "ListIterator")
              .stream().collect(Collectors.toMap(
                  t -> addKotlinPrefix("collections/Mutable" + t + ";"),
                  t -> "Ljava/util/" + t + ";")))
          .put(addKotlinPrefix("collections/Iterable;"), "Ljava/lang/Iterable;")
          .put(addKotlinPrefix("collections/MutableIterable;"), "Ljava/lang/Iterable;")
          .put(addKotlinPrefix("collections/Map.Entry;"), "Ljava/util/Map$Entry;")
          .put(addKotlinPrefix("collections/MutableMap.MutableEntry;"), "Ljava/util/Map$Entry;")
          // .../FunctionN -> .../jvm/functions/FunctionN
          .putAll(
              IntStream.rangeClosed(0, 22).boxed().collect(Collectors.toMap(
                  i -> addKotlinPrefix("Function" + i + ";"),
                  i -> addKotlinPrefix("jvm/functions/Function" + i + ";"))))
          .build();

  private static String remapKotlinType(String type) {
    if (knownTypeConversion.containsKey(type)) {
      return knownTypeConversion.get(type);
    }
    return type;
  }

  // Kotlin @Metadata deserialization has plain "kotlin", which will be relocated in r8lib.
  // See b/70169921#comment57 for more details.
  // E.g., desc: (Labc/xyz/C;Lkotlin/Function1;)kotlin/Unit
  // remapped desc would be: (Labc/xyz/C;Lkotlin/jvm/functions/Function1;)V
  private static String remapKotlinTypeInDesc(String desc, Reporter reporter) {
    if (desc == null) {
      return null;
    }
    if (desc.isEmpty()) {
      return desc;
    }
    String[] parameterTypes;
    try {
      parameterTypes = DescriptorUtils.getArgumentTypeDescriptors(desc);
      for (int i = 0; i < parameterTypes.length; i++) {
        parameterTypes[i] = remapKotlinType(parameterTypes[i]);
      }
    } catch (InvalidDescriptorException e) {
      // JvmMethodSignature from @Metadata is not 100% reliable (due to its own optimization using
      // map, relocation in r8lib, etc.)
      reporter.info(
          new StringDiagnostic(
              "Invalid descriptor (deserialized from Kotlin @Metadata): " + desc));
      return desc;
    }
    int index = desc.indexOf(')');
    assert 0 < index && index < desc.length() : desc;
    String returnType = remapKotlinType(desc.substring(index + 1));
    return "(" + StringUtils.join(Arrays.asList(parameterTypes), "") + ")" + returnType;
  }

  static JvmFieldSignature toJvmFieldSignature(DexField field) {
    return new JvmFieldSignature(field.name.toString(), field.type.toDescriptorString());
  }

  static JvmMethodSignature toJvmMethodSignature(DexMethod method) {
    StringBuilder descBuilder = new StringBuilder();
    descBuilder.append("(");
    for (DexType argType : method.proto.parameters.values) {
      descBuilder.append(argType.toDescriptorString());
    }
    descBuilder.append(")");
    descBuilder.append(method.proto.returnType.toDescriptorString());
    return new JvmMethodSignature(method.name.toString(), descBuilder.toString());
  }

  static class KmConstructorProcessor {
    private JvmMethodSignature signature = null;

    KmConstructorProcessor(KmConstructor kmConstructor, Reporter reporter) {
      kmConstructor.accept(new KmConstructorVisitor() {
        @Override
        public KmConstructorExtensionVisitor visitExtensions(KmExtensionType type) {
          if (type != JvmConstructorExtensionVisitor.TYPE) {
            return null;
          }
          return new JvmConstructorExtensionVisitor() {
            @Override
            public void visit(JvmMethodSignature desc) {
              assert signature == null : signature.asString();
              signature = desc;
            }
          };
        }
      });
      if (signature != null) {
        String remappedDesc = remapKotlinTypeInDesc(signature.getDesc(), reporter);
        if (remappedDesc != null && !remappedDesc.equals(signature.getDesc())) {
          signature = new JvmMethodSignature(signature.getName(), remappedDesc);
        }
      }
    }

    JvmMethodSignature signature() {
      return signature;
    }
  }

  static class KmFunctionProcessor {
    // Custom name via @JvmName("..."). Otherwise, null.
    private JvmMethodSignature signature = null;

    KmFunctionProcessor(KmFunction kmFunction, Reporter reporter) {
      kmFunction.accept(new KmFunctionVisitor() {
        @Override
        public KmFunctionExtensionVisitor visitExtensions(KmExtensionType type) {
          if (type != JvmFunctionExtensionVisitor.TYPE) {
            return null;
          }
          return new JvmFunctionExtensionVisitor() {
            @Override
            public void visit(JvmMethodSignature desc) {
              assert signature == null : signature.asString();
              signature = desc;
            }
          };
        }
      });
      if (signature != null) {
        String remappedDesc = remapKotlinTypeInDesc(signature.getDesc(), reporter);
        if (remappedDesc != null && !remappedDesc.equals(signature.getDesc())) {
          signature = new JvmMethodSignature(signature.getName(), remappedDesc);
        }
      }
    }

    JvmMethodSignature signature() {
      return signature;
    }
  }

  static class KmPropertyProcessor {
    private JvmFieldSignature fieldSignature = null;
    // Custom getter via @get:JvmName("..."). Otherwise, null.
    private JvmMethodSignature getterSignature = null;
    // Custom getter via @set:JvmName("..."). Otherwise, null.
    private JvmMethodSignature setterSignature = null;

    KmPropertyProcessor(KmProperty kmProperty, Reporter reporter) {
      kmProperty.accept(new KmPropertyVisitor() {
        @Override
        public KmPropertyExtensionVisitor visitExtensions(KmExtensionType type) {
          if (type != JvmPropertyExtensionVisitor.TYPE) {
            return null;
          }
          return new JvmPropertyExtensionVisitor() {
            @Override
            public void visit(
                int flags,
                JvmFieldSignature fieldDesc,
                JvmMethodSignature getterDesc,
                JvmMethodSignature setterDesc) {
              assert fieldSignature == null : fieldSignature.asString();
              fieldSignature = fieldDesc;
              assert getterSignature == null : getterSignature.asString();
              getterSignature = getterDesc;
              assert setterSignature == null : setterSignature.asString();
              setterSignature = setterDesc;
            }
          };
        }
      });
      if (fieldSignature != null) {
        String remappedDesc = remapKotlinType(fieldSignature.getDesc());
        if (remappedDesc != null && !remappedDesc.equals(fieldSignature.getDesc())) {
          fieldSignature = new JvmFieldSignature(fieldSignature.getName(), remappedDesc);
        }
      }
      if (getterSignature != null) {
        String remappedDesc = remapKotlinTypeInDesc(getterSignature.getDesc(), reporter);
        if (remappedDesc != null && !remappedDesc.equals(getterSignature.getDesc())) {
          getterSignature = new JvmMethodSignature(getterSignature.getName(), remappedDesc);
        }
      }
      if (setterSignature != null) {
        String remappedDesc = remapKotlinTypeInDesc(setterSignature.getDesc(), reporter);
        if (remappedDesc != null && !remappedDesc.equals(setterSignature.getDesc())) {
          setterSignature = new JvmMethodSignature(setterSignature.getName(), remappedDesc);
        }
      }
    }

    JvmFieldSignature fieldSignature() {
      return fieldSignature;
    }

    JvmMethodSignature getterSignature() {
      return getterSignature;
    }

    JvmMethodSignature setterSignature() {
      return setterSignature;
    }
  }
}
