extends GdUnitTestSuite

## NEO-85: dev hotbar bootstrap binds prototype_pulse to slot 0 when empty.

const HotbarState := preload("res://scripts/hotbar_state.gd")
const DEV_BOOTSTRAP_CAST_ABILITY_ID := "prototype_pulse"


class SpyHotbarClient:
	extends Node
	var bind_calls: Array = []

	func request_bind_slot(slot_index: int, ability_id: String) -> void:
		bind_calls.append([slot_index, ability_id])


class BootstrapHarness:
	extends Node
	var bootstrap_attempted: bool = false
	var _hotbar_state: Node
	var _hotbar_client: SpyHotbarClient

	func setup(parent: Node, slot0_ability: Variant) -> void:
		_hotbar_state = HotbarState.new()
		_hotbar_client = SpyHotbarClient.new()
		parent.add_child(_hotbar_state)
		parent.add_child(_hotbar_client)
		var rows: Array = []
		for i in range(8):
			var row: Dictionary = {"slotIndex": i}
			if i == 0 and slot0_ability is String:
				row["abilityId"] = slot0_ability
			rows.append(row)
		_hotbar_state.call("apply_slots", rows)

	func maybe_dev_bind_pulse_slot0() -> void:
		if bootstrap_attempted:
			return
		if not is_instance_valid(_hotbar_state) or not is_instance_valid(_hotbar_client):
			return
		var slots: Array = _hotbar_state.call("slots_snapshot") as Array
		if slots.is_empty():
			return
		var slot0: Variant = slots[0]
		if slot0 is String and not (slot0 as String).strip_edges().is_empty():
			return
		bootstrap_attempted = true
		_hotbar_client.request_bind_slot(0, DEV_BOOTSTRAP_CAST_ABILITY_ID)


func test_empty_slot0_triggers_pulse_bind_once() -> void:
	# Arrange
	var harness := BootstrapHarness.new()
	auto_free(harness)
	add_child(harness)
	harness.setup(self, null)
	# Act
	harness.maybe_dev_bind_pulse_slot0()
	harness.maybe_dev_bind_pulse_slot0()
	# Assert
	assert_that(harness._hotbar_client.bind_calls.size()).is_equal(1)
	assert_that(int(harness._hotbar_client.bind_calls[0][0])).is_equal(0)
	assert_that(str(harness._hotbar_client.bind_calls[0][1])).is_equal(
		DEV_BOOTSTRAP_CAST_ABILITY_ID
	)


func test_slot0_already_bound_skips_bootstrap() -> void:
	# Arrange
	var harness := BootstrapHarness.new()
	auto_free(harness)
	add_child(harness)
	harness.setup(self, "prototype_pulse")
	# Act
	harness.maybe_dev_bind_pulse_slot0()
	# Assert
	assert_that(harness._hotbar_client.bind_calls.size()).is_equal(0)
	assert_that(harness.bootstrap_attempted).is_false()
