package ru.dbotthepony.mc.otm.core.multiblock

import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.core.collect.WeakHashSet
import java.util.*

interface GlobalBlockEntityRemovalListener {
	fun blockEntityRemoved(blockEntity: BlockEntity): Boolean

	companion object {
		private val BLOCK_ENTITY_LISTENERS = WeakHashMap<Level, WeakHashMap<BlockEntity, WeakHashSet<GlobalBlockEntityRemovalListener>>>()

		fun onBlockEntityInvalidated(blockEntity: BlockEntity) {
			BLOCK_ENTITY_LISTENERS[blockEntity.level]?.get(blockEntity)?.forEach { it.blockEntityRemoved(blockEntity) }
			BLOCK_ENTITY_LISTENERS[blockEntity.level]?.remove(blockEntity)
		}

		fun listen(blockEntity: BlockEntity, listener: GlobalBlockEntityRemovalListener) {
			BLOCK_ENTITY_LISTENERS
				.computeIfAbsent(blockEntity.level) { WeakHashMap() }
				.computeIfAbsent(blockEntity) { WeakHashSet() }
				.add(listener)
		}

		fun stopListening(blockEntity: BlockEntity, listener: GlobalBlockEntityRemovalListener) {
			val levelMap = BLOCK_ENTITY_LISTENERS[blockEntity.level] ?: return
			val getSet = levelMap[blockEntity]

			if (getSet != null) {
				getSet.remove(listener)

				if (getSet.isEmpty()) {
					levelMap.remove(blockEntity)
				}
			}
		}
	}
}
