class_name TerrainQualityMeshCache
extends RefCounted

## Session-memory LRU owner for full-quality terrain Mesh references retained
## across tile unload/revisit. It owns no tile state, Node, RID, task or file.

const EXCLUDED_QUALITY_SOURCES: Array[String] = [
	"control_splat_cache",
	"splat_cache",
	"splat",
]

var _entries_by_tile_key: Dictionary = {}
var _tile_keys_oldest_to_newest: Array[String] = []


## Stores an admitted Mesh reference, touches it as newest and trims oldest
## entries to the supplied non-negative capacity. Returns false when rejected.
func store(tile_key: String, mesh: Mesh, source: String, capacity: int) -> bool:
	if tile_key.is_empty() or mesh == null or EXCLUDED_QUALITY_SOURCES.has(source):
		return false
	_entries_by_tile_key[tile_key] = {"mesh": mesh, "source": source}
	_touch(tile_key)
	_trim(maxi(0, capacity))
	return _entries_by_tile_key.has(tile_key)


## Returns a fresh record containing the retained Mesh/source and touches the key
## as newest. Missing or invalid records return empty and are removed.
func restore(tile_key: String) -> Dictionary:
	if not _entries_by_tile_key.has(tile_key):
		return {}
	var entry: Dictionary = _entries_by_tile_key[tile_key]
	var source := String(entry.get("source", "baked_full"))
	var mesh := entry.get("mesh") as Mesh
	if mesh == null or EXCLUDED_QUALITY_SOURCES.has(source):
		_remove(tile_key)
		return {}
	_touch(tile_key)
	return {"mesh": mesh, "source": source}


## Releases every retained Mesh reference and resets LRU order.
func clear() -> void:
	_entries_by_tile_key.clear()
	_tile_keys_oldest_to_newest.clear()


## Returns detached scalar diagnostics without exposing retained Mesh references.
func diagnostic_snapshot() -> Dictionary:
	var entries: Array[Dictionary] = []
	for tile_key in _tile_keys_oldest_to_newest:
		var entry: Dictionary = _entries_by_tile_key.get(tile_key, {})
		entries.append({"tile_key": tile_key, "source": String(entry.get("source", ""))})
	return {
		"entry_count": entries.size(),
		"entries_oldest_to_newest": entries,
	}


func _touch(tile_key: String) -> void:
	_tile_keys_oldest_to_newest.erase(tile_key)
	_tile_keys_oldest_to_newest.append(tile_key)


func _trim(capacity: int) -> void:
	while _tile_keys_oldest_to_newest.size() > capacity:
		_remove(_tile_keys_oldest_to_newest.front())


func _remove(tile_key: String) -> void:
	_entries_by_tile_key.erase(tile_key)
	_tile_keys_oldest_to_newest.erase(tile_key)
