package eu.mikroskeem.shuriken.instrumentation;

import eu.mikroskeem.shuriken.common.Ensure;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.*;

public final class ClassTools {
    /**
     * Unqualify class name <br>
     * In other words, <pre>foo.bar.baz</pre> -&gt; <pre>foo/bar/baz</pre>
     *
     * @param className Class name
     * @return Unqualified class name
     */
    @NotNull
    public static String unqualifyName(String className) {
        return Ensure.notNull(className, "Class name shouldn't be null!").replace(".", "/");
    }

    /**
     * Unqualify class name
     *
     * @see #unqualifyName(String)
     * @param clazz Class
     * @return Unqualified class name
     */
    @NotNull
    public static String unqualifyName(Class<?> clazz) {
        return unqualifyName(Ensure.notNull(clazz, "Class shouldn't be null!").getName());
    }

    /**
     * Get class signature for generic class implementing/extending
     *
     * @param genericClass Generic class
     * @param types Generic types
     * @return Signature string
     */
    @NotNull
    @Deprecated
    public static String getGenericSignature(Class<?> genericClass, Class<?>... types) {
        String genericName = unqualifyName(Ensure.notNull(genericClass, "Class shouldn't be null!").getName());
        StringBuilder sb = new StringBuilder();
        for(Class<?> type: types) sb.append("L").append(type.getSimpleName()).append(";");
        return "L" + genericName + "<" + sb.toString() + ">;";
    }

    /**
     * Generate simple <pre>super()</pre> calling constructor
     *
     * @param classWriter ClassWriter instance
     * @param superClass Super class name (use {@link Object} for non-extending classes
     *                   (or explictly extending Object, which is redundant anyway)
     * @deprecated Using ClassVisitor is better idea
     */
    @Deprecated
    public static void generateSimpleSuperConstructor(@NotNull ClassWriter classWriter, @NotNull String superClass) {
        generateSimpleSuperConstructor((ClassVisitor)classWriter, superClass);
    }

    /**
     * Generate simple <pre>super()</pre> calling constructor
     *
     * @param classVisitor ClassVisitor instance
     * @param superClass Super class name (use {@link Object} for non-extending classes
     *                   (or explictly extending Object, which is redundant anyway)
     */
    public static void generateSimpleSuperConstructor(@NotNull ClassVisitor classVisitor, @NotNull String superClass) {
        MethodVisitor mv = Ensure.notNull(classVisitor, "ClassWriter shouldn't be null!")
                .visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, unqualifyName(superClass), "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 0);
        mv.visitEnd();
    }

    /**
     * Generate simple <pre>super()</pre> calling constructor
     *
     * @param classWriter ClassWriter instance
     * @param superClass Super class object (use {@link Object} for non-extending classes
     *                   (or explictly extending Object, which is redundant anyway)
     * @deprecated Using ClassVisitor is better idea
     */
    @Deprecated
    public static void generateSimpleSuperConstructor(@NotNull ClassWriter classWriter, @NotNull Class<?> superClass) {
        generateSimpleSuperConstructor((ClassVisitor)classWriter, Ensure.notNull(superClass, "Class shouldn't be null").getName());
    }

    /**
     * Generate simple <pre>super()</pre> calling constructor
     *
     * @param classVisitor ClassWriter instance
     * @param superClass Super class object (use {@link Object} for non-extending classes
     *                   (or explictly extending Object, which is redundant anyway)
     */
    public static void generateSimpleSuperConstructor(@NotNull ClassVisitor classVisitor, @NotNull Class<?> superClass) {
        generateSimpleSuperConstructor(classVisitor, Ensure.notNull(superClass, "Class shouldn't be null").getName());
    }
}
@@ -1021,1222 +1021,8 @@
  %7D%0A%0A
-    /**%0A     * Get class signature for generic class implementing/extending%0A     *%0A     * @param genericClass Generic class%0A     * @param types Generic types%0A     * @return Signature string%0A     */%0A    @NotNull%0A    @Deprecated%0A    public static String getGenericSignature(Class%3C?%3E genericClass, Class%3C?%3E... types) %7B%0A        String genericName = unqualifyName(Ensure.notNull(genericClass, %22Class shouldn't be null!%22).getName());%0A        StringBuilder sb = new StringBuilder();%0A        for(Class%3C?%3E type: types) sb.append(%22L%22).append(type.getSimpleName()).append(%22;%22);%0A        return %22L%22 + genericName + %22%3C%22 + sb.toString() + %22%3E;%22;%0A    %7D%0A%0A    /**%0A     * Generate simple %3Cpre%3Esuper()%3C/pre%3E calling constructor%0A     *%0A     * @param classWriter ClassWriter instance%0A     * @param superClass Super class name (use %7B@link Object%7D for non-extending classes%0A     *                   (or explictly extending Object, which is redundant anyway)%0A     * @deprecated Using ClassVisitor is better idea%0A     */%0A    @Deprecated%0A    public static void generateSimpleSuperConstructor(@NotNull ClassWriter classWriter, @NotNull String superClass) %7B%0A        generateSimpleSuperConstructor((ClassVisitor)classWriter, superClass);%0A    %7D%0A%0A
     
@@ -1849,642 +1849,8 @@
  %7D%0A%0A
-    /**%0A     * Generate simple %3Cpre%3Esuper()%3C/pre%3E calling constructor%0A     *%0A     * @param classWriter ClassWriter instance%0A     * @param superClass Super class object (use %7B@link Object%7D for non-extending classes%0A     *                   (or explictly extending Object, which is redundant anyway)%0A     * @deprecated Using ClassVisitor is better idea%0A     */%0A    @Deprecated%0A    public static void generateSimpleSuperConstructor(@NotNull ClassWriter classWriter, @NotNull Class%3C?%3E superClass) %7B%0A        generateSimpleSuperConstructor((ClassVisitor)classWriter, Ensure.notNull(superClass, %22Class shouldn't be null%22).getName());%0A    %7D%0A%0A
     

Remove deprecated methods