class_name WmoPlacementRegistry
extends RefCounted

## Owns WMO placement-key to tile/global reference-key sets without Nodes.

var _reference_keys_by_placement_key: Dictionary = {}


## Adds one idempotent reference and returns true only for a newly registered
## placement key. Empty placement/reference keys are rejected.
func add_reference(placement_key: String, reference_key: String) -> bool:
	if placement_key.is_empty() or reference_key.is_empty():
		return false
	var is_new_placement := not _reference_keys_by_placement_key.has(placement_key)
	if is_new_placement:
		_reference_keys_by_placement_key[placement_key] = {}
	var reference_keys: Dictionary = _reference_keys_by_placement_key[placement_key]
	reference_keys[reference_key] = true
	return is_new_placement


## Releases one reference and returns true only when the final reference removes
## the placement key. Unknown and non-owner references leave state unchanged.
func release_reference(placement_key: String, reference_key: String) -> bool:
	if placement_key.is_empty() or reference_key.is_empty():
		return false
	if not _reference_keys_by_placement_key.has(placement_key):
		return false
	var reference_keys: Dictionary = _reference_keys_by_placement_key[placement_key]
	if not reference_keys.has(reference_key):
		return false
	reference_keys.erase(reference_key)
	if not reference_keys.is_empty():
		return false
	_reference_keys_by_placement_key.erase(placement_key)
	return true


## Returns whether the placement key currently has at least one reference.
func contains(placement_key: String) -> bool:
	return not placement_key.is_empty() and _reference_keys_by_placement_key.has(placement_key)


## Removes every placement/reference record. Safe to call repeatedly.
func clear() -> void:
	_reference_keys_by_placement_key.clear()


## Returns the number of currently referenced placement keys.
func active_count() -> int:
	return _reference_keys_by_placement_key.size()


## Returns detached, placement/reference-key-sorted diagnostic records.
func diagnostic_snapshot() -> Array[Dictionary]:
	var placement_keys: Array = _reference_keys_by_placement_key.keys()
	placement_keys.sort()
	var snapshot: Array[Dictionary] = []
	for placement_key_variant in placement_keys:
		var placement_key := String(placement_key_variant)
		var reference_keys: Array = (
			_reference_keys_by_placement_key[placement_key] as Dictionary
		).keys()
		reference_keys.sort()
		snapshot.append({
			"placement_key": placement_key,
			"reference_keys": reference_keys.duplicate(),
		})
	return snapshot
