package com.zivilon.cinder_loe.coremod;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;

import net.minecraft.launchwrapper.IClassTransformer;

public class UrukBerserkerGreatswordPatcher implements IClassTransformer {
    @Override
    public byte[] transform(String name, String transformedName, byte[] basicClass) {
        if (!name.equals("lotr.common.LOTRMod")) return basicClass;
        ClassReader cr = new ClassReader(basicClass);
        ClassNode cn = new ClassNode();
        cr.accept(cn, 0);

        for (MethodNode mn : cn.methods) {
            if (!mn.name.equals("preload")) continue;

            AbstractInsnNode insn = mn.instructions.getFirst();
            while (insn != null) {
                if (insn.getOpcode() == Opcodes.NEW && insn instanceof TypeInsnNode) {
                    if (((TypeInsnNode) insn).desc.equals("lotr/common/item/LOTRItemSword")) {
                        AbstractInsnNode search = insn.getNext();
                        boolean patchThis = false;
                        while (search != null) {
                            if (search.getOpcode() == Opcodes.NEW && search != insn) {
                                break;
                            }
                            if (search.getOpcode() == Opcodes.PUTSTATIC && search instanceof FieldInsnNode) {
                                FieldInsnNode fin = (FieldInsnNode) search;
                                if (fin.owner.equals("lotr/common/LOTRMod") &&
                                    fin.name.equals("scimitarUrukBerserker")) {
                                    patchThis = true;
                                    break;
                                }
                            }
                            search = search.getNext();
                        }
                        if (patchThis) {
                            ((TypeInsnNode) insn).desc = "com/zivilon/cinder_loe/items/LoEGreatSword";
                            AbstractInsnNode patch = insn.getNext();
                            while (patch != null) {
                                if (patch.getOpcode() == Opcodes.INVOKESPECIAL && patch instanceof MethodInsnNode) {
                                    MethodInsnNode mi = (MethodInsnNode) patch;
                                    if (mi.owner.equals("lotr/common/item/LOTRItemSword")) {
                                        mi.owner = "com/zivilon/cinder_loe/items/LoEGreatSword";
                                        break;
                                    }
                                }
                                patch = patch.getNext();
                            }
                            System.out.println("[UrukBerserkerGreatswordPatcher] Patched the scimitarUrukBerserker sword to LoEGreatSword");
                        }
                    }
                }
                insn = insn.getNext();
            }
        }
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
        cn.accept(cw);
        return cw.toByteArray();
    }
}
