package ru.dbotthepony.mc.otm.capability.drive

import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.math.BigInteger
import ru.dbotthepony.mc.otm.core.math.serializeNBT
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.storage.IStorageTuple
import ru.dbotthepony.mc.otm.storage.ItemStorageStack
import ru.dbotthepony.mc.otm.storage.StorageStack
import java.math.BigInteger
import java.util.*

class ItemMatteryDrive : AbstractMatteryDrive<ItemStorageStack>, IItemMatteryDrive {
	constructor(capacity: BigInteger, maxDifferentStacks: Int) : super(capacity, maxDifferentStacks = maxDifferentStacks)
	constructor(capacity: BigInteger, uuid: UUID, maxDifferentStacks: Int) : super(capacity, uuid, maxDifferentStacks)
	constructor(capacity: BigInteger, uuid: UUID) : super(capacity, uuid)
	constructor(capacity: BigInteger) : super(capacity)

	override val storageType: StorageStack.Type<ItemStorageStack> = StorageStack.ITEMS

	fun insertStack(item: ItemStack, simulate: Boolean): ItemStack {
		return insertStack(ItemStorageStack(item), simulate).toItemStack()
	}

	override fun serializeStack(item: ItemStorageStack): CompoundTag {
		val tag = CompoundTag()
		tag["item"] = item.toItemStack(1).serializeNBT()
		tag["count"] = item.count.serializeNBT()
		return tag
	}

	override fun deserializeStack(tag: CompoundTag): ItemStorageStack? {
		if ("item" in tag && "count" in tag) {
			val item = tag["item"] as? CompoundTag ?: return null
			val count = BigInteger(tag["count"])
			return ItemStorageStack.unsafe(ItemStack.of(item), count)
		}

		return null
	}

	override fun findItems(item: Item): List<IStorageTuple<ItemStorageStack>> {
		val list = ArrayList<IStorageTuple<ItemStorageStack>>()

		for ((key, value) in stack2tuples.entries) {
			if (key.item === item) {
				list.add(value)
			}
		}

		return list
	}

	override fun findItems(stack: ItemStack): IStorageTuple<ItemStorageStack>? {
		return stack2tuples[ItemStorageStack.unsafe(stack)]
	}

	companion object {
		@JvmField
		val DUMMY = ItemMatteryDrive(BigInteger.ZERO, UUID(0L, 0L), 0)
	}
}
