package me.towdium.jecharacters.transform.transformers;

import it.unimi.dsi.fastutil.ints.IntSet;
import mcp.MethodsReturnNonnullByDefault;
import me.towdium.jecharacters.JechConfig;
import me.towdium.jecharacters.core.JechCore;
import me.towdium.jecharacters.match.PinyinTree;
import me.towdium.jecharacters.transform.Transformer;
import mezz.jei.suffixtree.GeneralizedSuffixTree;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;

import javax.annotation.ParametersAreNonnullByDefault;

/**
 * Author: Towdium
 * Date:   13/06/17
 */

public class TransformerJei extends Transformer.Default {
    @SuppressWarnings("unused")
    public static String wrap(String s) {
        return "\"" + s + "\"";
    }

    @Override
    public boolean accepts(String name) {
        return JechConfig.enableJEI && name.equals("mezz.jei.ingredients.IngredientFilter");
    }

    @Override
    public void transform(ClassNode n) {
        JechCore.LOG.info("Transforming class " + n.name + " for JEI integration.");
        Transformer.findMethod(n, "<init>").ifPresent(methodNode ->
                Transformer.transformConstruct(methodNode, "mezz/jei/suffixtree/GeneralizedSuffixTree",
                        "me/towdium/jecharacters/transform/transformers/TransformerJei$FakeTree"));
        Transformer.findMethod(n, "createPrefixedSearchTree").ifPresent(methodNode ->
                Transformer.transformConstruct(methodNode, "mezz/jei/suffixtree/GeneralizedSuffixTree",
                        "me/towdium/jecharacters/transform/transformers/TransformerJei$FakeTree"));
        if (JechConfig.enableForceQuote) Transformer.findMethod(n, "getElements").ifPresent(methodNode -> {
            InsnList list = methodNode.instructions;
            list.insert(list.get(3), new MethodInsnNode(Opcodes.INVOKESTATIC,
                    "me/towdium/jecharacters/transform/transformers/TransformerJei", "wrap",
                    "(Ljava/lang/String;)Ljava/lang/String;", false));
        });
    }

    @ParametersAreNonnullByDefault
    @MethodsReturnNonnullByDefault
    public static class FakeTree extends GeneralizedSuffixTree {
        PinyinTree graph = new PinyinTree();

        public IntSet search(String word) {
            return graph.search(word);
        }

        public void put(String key, int index) throws IllegalStateException {
            //super.put(key, index);
            graph.put(key, index);
        }
    }
}

@@ -2272,16 +2272,47 @@
 nTree();
+%0A        int highestIndex = -1;
 %0A%0A      
@@ -2493,66 +2493,454 @@
     
-//super.put(key, index);%0A            graph.put(key, index)
+if (index %3C highestIndex) %7B%0A                String err = %22The input index must not be less than any of the previously %22 +%0A                        %22inserted ones. Got %22 + index + %22, expected at least %22 + highestIndex;%0A                throw new IllegalStateException(err);%0A            %7D else highestIndex = index;%0A            graph.put(key, index);%0A        %7D%0A%0A        @Override%0A        public int getHighestIndex() %7B%0A            return highestIndex
 ;%0A  

Fix index update