// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.lang.jvm.types;

import gnu.trove.THashMap;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import static com.intellij.psi.CommonClassNames.*;

/**
 * @since 2018.2
 */
public final class JvmPrimitiveTypeKind {

  public static final JvmPrimitiveTypeKind BOOLEAN = new JvmPrimitiveTypeKind("boolean", JAVA_LANG_BOOLEAN);
  public static final JvmPrimitiveTypeKind BYTE = new JvmPrimitiveTypeKind("byte", JAVA_LANG_BYTE);
  public static final JvmPrimitiveTypeKind CHAR = new JvmPrimitiveTypeKind("char", JAVA_LANG_CHARACTER);
  public static final JvmPrimitiveTypeKind DOUBLE = new JvmPrimitiveTypeKind("double", JAVA_LANG_DOUBLE);
  public static final JvmPrimitiveTypeKind FLOAT = new JvmPrimitiveTypeKind("float", JAVA_LANG_FLOAT);
  public static final JvmPrimitiveTypeKind INT = new JvmPrimitiveTypeKind("int", JAVA_LANG_INTEGER);
  public static final JvmPrimitiveTypeKind LONG = new JvmPrimitiveTypeKind("long", JAVA_LANG_LONG);
  public static final JvmPrimitiveTypeKind SHORT = new JvmPrimitiveTypeKind("short", JAVA_LANG_SHORT);
  public static final JvmPrimitiveTypeKind VOID = new JvmPrimitiveTypeKind("void", JAVA_LANG_VOID);

  private final String myName;
  private final String myBoxedFqn;

  private JvmPrimitiveTypeKind(String name, String boxedFqn) {
    myName = name;
    myBoxedFqn = boxedFqn;
  }

  @Contract(pure = true)
  @NotNull
  public String getName() {
    return myName;
  }

  @Contract(pure = true)
  @NotNull
  public String getBoxedFqn() {
    return myBoxedFqn;
  }

  private static final Map<String, JvmPrimitiveTypeKind> ourNameToKind;
  private static final Map<String, JvmPrimitiveTypeKind> ourFqnToKind;

  static {
    JvmPrimitiveTypeKind[] values = {BOOLEAN, BYTE, CHAR, DOUBLE, FLOAT, INT, LONG, SHORT, VOID};
    THashMap<String, JvmPrimitiveTypeKind> nameToKind = new THashMap<>();
    THashMap<String, JvmPrimitiveTypeKind> fqnToKind = new THashMap<>();
    for (JvmPrimitiveTypeKind kind : values) {
      nameToKind.put(kind.getName(), kind);
      fqnToKind.put(kind.getBoxedFqn(), kind);
    }
    nameToKind.compact();
    fqnToKind.compact();
    ourNameToKind = nameToKind;
    ourFqnToKind = fqnToKind;
  }

  @Contract(value = "null -> null", pure = true)
  @Nullable
  public static JvmPrimitiveTypeKind getKindByName(@Nullable String name) {
    return ourNameToKind.get(name);
  }

  @Contract(value = "null -> null", pure = true)
  @Nullable
  public static JvmPrimitiveTypeKind getKindByFqn(@Nullable String fqn) {
    return ourFqnToKind.get(fqn);
  }

  @Contract(pure = true)
  @NotNull
  public static Collection<String> getBoxedFqns() {
    return Collections.unmodifiableCollection(ourFqnToKind.keySet());
  }
}

@@ -636,16 +636,21 @@
 _BOOLEAN
+, %22Z%22
 );%0A  pub
@@ -741,16 +741,21 @@
 ANG_BYTE
+, %22B%22
 );%0A  pub
@@ -851,16 +851,21 @@
 HARACTER
+, %22C%22
 );%0A  pub
@@ -962,16 +962,21 @@
 G_DOUBLE
+, %22D%22
 );%0A  pub
@@ -1070,16 +1070,21 @@
 NG_FLOAT
+, %22F%22
 );%0A  pub
@@ -1176,16 +1176,21 @@
 _INTEGER
+, %22I%22
 );%0A  pub
@@ -1281,16 +1281,21 @@
 ANG_LONG
+, %22J%22
 );%0A  pub
@@ -1389,16 +1389,21 @@
 NG_SHORT
+, %22S%22
 );%0A  pub
@@ -1494,16 +1494,21 @@
 ANG_VOID
+, %22V%22
 );%0A%0A  pr
@@ -1568,16 +1568,53 @@
 oxedFqn;
+%0A  private final String myBinaryName;
 %0A%0A  priv
@@ -1666,16 +1666,35 @@
 boxedFqn
+, String binaryName
 ) %7B%0A    
@@ -1731,24 +1731,55 @@
 = boxedFqn;%0A
+    myBinaryName = binaryName;%0A
   %7D%0A%0A  @Cont
@@ -1955,16 +1955,116 @@
 n;%0A  %7D%0A%0A
+  @Contract(pure = true)%0A  @NotNull%0A  public String getBinaryName() %7B%0A    return myBinaryName;%0A  %7D%0A%0A
   privat

add JvmPrimitiveTypeKind#getBinaryName