package ru.dbotthepony.kstarbound.defs.quest

import com.google.common.collect.ImmutableList
import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.annotations.JsonAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import ru.dbotthepony.kommons.io.readCollection
import ru.dbotthepony.kommons.io.writeBinaryString
import ru.dbotthepony.kommons.io.writeCollection
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.VersionRegistry
import ru.dbotthepony.kstarbound.io.readInternedString
import ru.dbotthepony.kstarbound.json.VersionedAdapter
import ru.dbotthepony.kstarbound.json.VersionedJson
import ru.dbotthepony.kstarbound.json.builder.FactoryAdapter
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.json.getAdapter
import ru.dbotthepony.kstarbound.network.syncher.legacyCodec
import ru.dbotthepony.kstarbound.network.syncher.nativeCodec
import java.io.DataInputStream
import java.io.DataOutputStream

@JsonAdapter(QuestArcDescriptor.Adapter::class)
data class QuestArcDescriptor(
	val quests: ImmutableList<QuestDescriptor> = ImmutableList.of(),
	val stagehandUniqueId: String? = null,
) {
	constructor(stream: DataInputStream, isLegacy: Boolean) : this(
		ImmutableList.copyOf(stream.readCollection { QuestDescriptor(this, isLegacy) }),
		if (stream.readBoolean()) stream.readInternedString() else null
	)

	fun write(stream: DataOutputStream, isLegacy: Boolean) {
		stream.writeCollection(quests) { it.write(this, isLegacy) }
		stream.writeBoolean(stagehandUniqueId != null)
		if (stagehandUniqueId != null) stream.writeBinaryString(stagehandUniqueId)
	}

	class Adapter(gson: Gson) : VersionedAdapter<QuestArcDescriptor>("QuestArcDescriptor", FactoryAdapter.createFor(QuestArcDescriptor::class, gson))

	companion object {
		val CODEC = nativeCodec(::QuestArcDescriptor, QuestArcDescriptor::write)
		val LEGACY_CODEC = legacyCodec(::QuestArcDescriptor, QuestArcDescriptor::write)
	}
}
