package ru.dbotthepony.kstarbound.network.syncher

import com.google.gson.TypeAdapter
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import ru.dbotthepony.kommons.io.StreamCodec
import ru.dbotthepony.kommons.io.readByteArray
import ru.dbotthepony.kommons.io.writeByteArray
import ru.dbotthepony.kstarbound.json.BinaryJsonReader
import ru.dbotthepony.kstarbound.json.writeJsonElement
import java.io.DataInputStream
import java.io.DataOutputStream

class JsonCodec<V>(val adapter: TypeAdapter<V>, val wrapIntoArray: Boolean = false) : StreamCodec<V> {
	override fun copy(value: V): V {
		return value
	}

	override fun read(stream: DataInputStream): V {
		if (wrapIntoArray) {
			return adapter.read(BinaryJsonReader(FastByteArrayInputStream(stream.readByteArray())))
		} else {
			return adapter.read(BinaryJsonReader(stream))
		}
	}

	override fun write(stream: DataOutputStream, value: V) {
		if (wrapIntoArray) {
			val output = FastByteArrayOutputStream()
			DataOutputStream(output).writeJsonElement(adapter.toJsonTree(value))
			stream.writeByteArray(output.array, 0, output.length)
		} else {
			stream.writeJsonElement(adapter.toJsonTree(value))
		}
	}
}
