package ru.dbotthepony.kstarbound.json.factory

import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap
import com.google.gson.JsonSyntaxException
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import ru.dbotthepony.kommons.gson.consumeNull

class ImmutableArrayMapTypeAdapter<K, V>(val keyAdapter: TypeAdapter<K>, val elementAdapter: TypeAdapter<V>) : TypeAdapter<ImmutableMap<K, V>>() {
	override fun write(out: JsonWriter, value: ImmutableMap<K, V>?) {
		if (value == null) {
			out.nullValue()
			return
		}

		out.beginArray()

		for ((k, v) in value) {
			keyAdapter.write(out, k)
			elementAdapter.write(out, v)
		}

		out.endArray()
	}

	override fun read(reader: JsonReader): ImmutableMap<K, V>? {
		if (reader.consumeNull())
			return null

		reader.beginArray()

		val builder = ImmutableMap.Builder<K, V>()

		while (reader.peek() != JsonToken.END_OBJECT) {
			builder.put(
				keyAdapter.read(reader) ?: throw JsonSyntaxException("Nulls as keys are not allowed, near ${reader.path}"),
				elementAdapter.read(reader) ?: throw JsonSyntaxException("Nulls as values are not allowed, near ${reader.path}"))
		}

		reader.endArray()
		return builder.build()
	}
}
