package ru.dbotthepony.mc.otm.registry

import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.neoforged.neoforge.registries.NewRegistryEvent
import net.neoforged.neoforge.registries.RegistryBuilder
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.ResourceLocation
import java.util.function.Supplier
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

class RegistryDelegate<T>(key: String, private val configurator: RegistryBuilder<T>.() -> Unit = {}) : ReadOnlyProperty<Any, Registry<T>>, Supplier<Registry<T>>, Lazy<Registry<T>> {
	private var _value: Registry<T>? = null

	override val value: Registry<T>
		get() = get()

	override fun isInitialized(): Boolean {
		return _value != null
	}

	val location = ResourceLocation(OverdriveThatMatters.MOD_ID, key)
	val key: ResourceKey<Registry<T>> = ResourceKey.createRegistryKey(location)

	override fun get(): Registry<T> {
		val value = _value ?: throw IllegalStateException("Tried to access uninitialized registry $location")
		return value
	}

	override fun getValue(thisRef: Any, property: KProperty<*>): Registry<T> {
		return get()
	}

	fun build(event: NewRegistryEvent) {
		if (_value != null) {
			throw IllegalStateException("Already built registry $location!")
		}

		_value = RegistryBuilder(key).let {
			configurator.invoke(it)
			event.create(it)
		}
	}
}
