
var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI')
var Opcodes = Java.type('org.objectweb.asm.Opcodes')
var MethodNode = Java.type('org.objectweb.asm.tree.MethodNode')
var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode')
var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode')
var InsnNode = Java.type('org.objectweb.asm.tree.InsnNode')
var TypeInsnNode = Java.type('org.objectweb.asm.tree.TypeInsnNode')

var classesToPatch = [
	'net.minecraft.world.entity.vehicle.ChestBoat',
	'net.minecraft.world.level.block.entity.BarrelBlockEntity',
	'net.minecraft.world.level.block.entity.ChestBlockEntity',
	'net.minecraft.world.level.block.EnderChestBlock',
	'net.minecraft.world.entity.vehicle.MinecartChest',
	'net.minecraft.world.level.block.ChestBlock$2$1'
]

var isOwnPatches = [
	'net.minecraft.world.level.block.entity.BarrelBlockEntity$1',
	'net.minecraft.world.level.block.entity.ChestBlockEntity$1',
]

function patchMethod(node) {
	if (node.desc.endsWith('AbstractContainerMenu;')) {
		var threeRows = ASMAPI.mapMethod('m_39237_')
		var sixRows = ASMAPI.mapMethod('m_39246_')

		for (var i = 0; i < node.instructions.size(); i++) {
			var instr = node.instructions.get(i)

			if (instr.getOpcode() == Opcodes.INVOKESTATIC && instr.name == threeRows && instr.owner == 'net/minecraft/world/inventory/ChestMenu') {
				node.instructions.set(instr, new MethodInsnNode(
					Opcodes.INVOKESTATIC,
					'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu',
					'c9x3',
					'(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;)Lru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu;'
				))

				break
			} else if (instr.getOpcode() == Opcodes.INVOKESTATIC && instr.name == sixRows && instr.owner == 'net/minecraft/world/inventory/ChestMenu') {
				node.instructions.set(instr, new MethodInsnNode(
					Opcodes.INVOKESTATIC,
					'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu',
					'c9x6',
					'(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;)Lru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu;'
				))

				break
			}
		}
	}
}

function initializeCoreMod() {
	var result = {}

	for (i in classesToPatch) {
		var clazz = classesToPatch[i]

		result[clazz] = {
			'target': {
				'type': 'CLASS',
				'name': clazz
			},
			'transformer': function(classNode) {
				for (var i = 0; i < classNode.methods.size(); i++) {
					patchMethod(classNode.methods.get(i))
				}

				return classNode
			}
		}
	}

	for (i in isOwnPatches) {
		var clazz = isOwnPatches[i]

		result[clazz] = {
			'target': {
				'type': 'METHOD',
				'class': clazz,
				'methodName': ASMAPI.mapMethod('m_142718_'),
				'methodDesc': '(Lnet/minecraft/world/entity/player/Player;)Z'
			},
			'transformer': function(node) {
				for (var i = 0; i < node.instructions.size(); i++) {
					var instr = node.instructions.get(i)

					if ((instr.getOpcode() == Opcodes.INSTANCEOF || instr.getOpcode() == Opcodes.CHECKCAST) && instr.desc == 'net/minecraft/world/inventory/ChestMenu') {
						instr.desc = 'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu'
					} else if (instr.getOpcode() == Opcodes.INVOKEVIRTUAL && instr.owner == 'net/minecraft/world/inventory/ChestMenu' && instr.name == ASMAPI.mapMethod('m_39261_')) {
						instr.owner = 'ru/dbotthepony/mc/otm/compat/vanilla/MatteryChestMenu'
						instr.name = 'getContainer'
					}
				}

				return node
			}
		}
	}

	return result
}
