package ru.dbotthepony.kstarbound

import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
import ru.dbotthepony.kstarbound.json.VersionedJson
import java.util.concurrent.Future

object VersionRegistry {
	private val versions = Object2IntOpenHashMap<String>()

	fun currentVersion(name: String): Int {
		return versions.getInt(name)
	}

	fun make(name: String, contents: JsonElement): VersionedJson {
		return VersionedJson(name, currentVersion(name), contents)
	}

	fun <T> load(name: String, reader: JsonReader, adapter: TypeAdapter<T>): T {
		val read = this.adapter.read(reader) ?: throw NullPointerException("Expected versioned json $name, but found null")

		if (read.version != currentVersion(name)) {
			throw IllegalStateException("NYI: Migrating $name from ${read.version} to ${currentVersion(name)}")
		}

		return adapter.fromJsonTree(read.content)
	}

	private val adapter by lazy { Starbound.gson.getAdapter(VersionedJson::class.java) }

	fun load(patchTree: Map<String, List<IStarboundFile>>): Future<*> {
		return Starbound.EXECUTOR.submit(Runnable {
			val json = Starbound.loadJsonAsset("/versioning.config") ?: throw NoSuchElementException("Unable to load /versioning.config! Expect HUGE problems!")
			json as JsonObject

			for ((k, v) in json.entrySet()) {
				versions[k] = v.asInt
			}
		})
	}
}
