package ru.dbotthepony.mc.otm.core.util

import com.google.gson.JsonElement
import com.mojang.serialization.Codec
import com.mojang.serialization.DataResult
import com.mojang.serialization.JsonOps
import io.netty.buffer.ByteBufInputStream
import io.netty.buffer.ByteBufOutputStream
import io.netty.handler.codec.DecoderException
import io.netty.handler.codec.EncoderException
import net.minecraft.nbt.NbtAccounter
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.chat.Component

fun FriendlyByteBuf.readBinaryJson(): JsonElement {
	return ByteBufInputStream(this).readBinaryJson()
}

fun FriendlyByteBuf.writeBinaryJson(value: JsonElement) {
	ByteBufOutputStream(this).writeBinaryJson(value)
}

fun <S> FriendlyByteBuf.writeBinaryJsonWithCodec(codec: Codec<S>, value: S) {
	writeBinaryJson(codec.encode(value, JsonOps.INSTANCE, JsonOps.INSTANCE.empty()).mapOrElse({ it }, { throw EncoderException("Failed to encode input data: ${it.message()}") }))
}

fun <S> FriendlyByteBuf.readBinaryJsonWithCodec(codec: Codec<S>): S {
	return codec.decode(JsonOps.INSTANCE, readBinaryJson())
		.mapOrElse({ it.first }, { throw DecoderException("Failed to decode data from network: ${it.message()}") })
}

fun <S> FriendlyByteBuf.readBinaryJsonWithCodecIndirect(codec: Codec<S>): DataResult<S> {
	return codec.decode(JsonOps.INSTANCE, readBinaryJson()).map { it.first }
}

// обратный порядок аргументов у лямбда выражения
fun <T> FriendlyByteBuf.writeCollection(collection: Collection<T>, writer: (T, FriendlyByteBuf) -> Unit) {
	writeCollection(collection) { a, b -> writer.invoke(b, a) }
}
