package ru.dbotthepony.mc.otm.data

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonObject
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSyntaxException
import com.mojang.serialization.Codec
import net.minecraft.world.level.storage.loot.Serializer
import ru.dbotthepony.mc.otm.core.fromJsonStrict
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.core.toJsonStrict

class Codec2Serializer<T : Any>(val codec: Codec<T>, val embed: Boolean = true) : Serializer<T> {
	override fun serialize(data: JsonObject, value: T, context: JsonSerializationContext) {
		if (embed) {
			val result = codec.toJsonStrict(value, data)

			if (result !is JsonObject) {
				throw RuntimeException("Expected JsonObject from codec, got ${result::class.qualifiedName}")
			}

			val keys = ArrayList(data.keySet())
			for (k in keys) data.remove(k)
			for ((k, v) in result.entrySet()) data[k] = v
		} else {
			data["value"] = codec.toJsonStrict(value)
		}
	}

	override fun deserialize(data: JsonObject, context: JsonDeserializationContext): T {
		if (embed) {
			return codec.fromJsonStrict(data)
		} else {
			return codec.fromJsonStrict(data["value"] ?: throw JsonSyntaxException("Missing 'value' element"))
		}
	}
}
