package ru.dbotthepony.kstarbound.server.world

import com.google.gson.JsonObject
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.arrays.Object2DArray
import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kstarbound.defs.EntityType
import ru.dbotthepony.kstarbound.json.VersionedJson
import ru.dbotthepony.kstarbound.math.vector.Vector2d
import ru.dbotthepony.kstarbound.world.ChunkPos
import ru.dbotthepony.kstarbound.world.ChunkState
import ru.dbotthepony.kstarbound.world.WorldGeometry
import ru.dbotthepony.kstarbound.world.api.AbstractCell
import ru.dbotthepony.kstarbound.world.entities.AbstractEntity
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
import java.io.Closeable
import java.io.DataInputStream
import java.util.concurrent.CompletableFuture
import java.util.zip.InflaterInputStream

abstract class WorldStorage : Closeable {
	data class Metadata(val geometry: WorldGeometry, val data: VersionedJson)
	data class ChunkCells(val cells: Object2DArray<out AbstractCell>, val state: ChunkState)

	abstract fun loadCells(pos: ChunkPos): CompletableFuture<ChunkCells?>
	abstract fun loadEntities(pos: ChunkPos): CompletableFuture<Collection<AbstractEntity>>
	abstract fun loadMetadata(): CompletableFuture<Metadata?>

	abstract fun saveEntities(pos: ChunkPos, entities: Collection<AbstractEntity>)
	abstract fun saveCells(pos: ChunkPos, data: ChunkCells)
	abstract fun saveMetadata(data: Metadata)

	// original method of storing and indexing unique entities is crude
	// good thing we will only ever work with memory backed storage when dealing
	// with legacy data storage (I HOPE)
	data class UniqueEntitySearchResult(val chunk: ChunkPos, val pos: Vector2d)
	abstract fun findUniqueEntity(identifier: String): CompletableFuture<UniqueEntitySearchResult?>

	/**
	 * closes storage, discarding any un[commit]ted data
	 */
	override fun close() {}

	abstract fun commit()
}
