class_name M2BuildDispatchPlanner
extends RefCounted

## Selects the next M2 build action from already observed resource state.
## The planner retains no state or engine-object references.

const ACTION_WAIT_FOR_ANIMATION := &"wait_for_animation"
const ACTION_MATERIALIZE_ANIMATED := &"materialize_animated"
const ACTION_WAIT_FOR_STATIC_MESH := &"wait_for_static_mesh"
const ACTION_MATERIALIZE_STATIC := &"materialize_static"
const ACTION_ADVANCE_WITHOUT_MATERIALIZATION := &"advance_without_materialization"


## Returns a detached action/transition plan for one M2 build operation.
func plan_step(
	batch_count: int,
	resource_snapshot: RefCounted
) -> Dictionary:
	if resource_snapshot == null:
		return _wait_plan(ACTION_WAIT_FOR_STATIC_MESH)
	if bool(resource_snapshot.call("animation_request_pending")):
		return _wait_plan(ACTION_WAIT_FOR_ANIMATION)
	if batch_count <= 0:
		return _advance_plan(ACTION_ADVANCE_WITHOUT_MATERIALIZATION, false)
	if bool(resource_snapshot.call("has_animated_prototype")):
		return _advance_plan(ACTION_MATERIALIZE_ANIMATED, true)
	if bool(resource_snapshot.call("has_static_mesh")):
		return _advance_plan(ACTION_MATERIALIZE_STATIC, true)
	if bool(resource_snapshot.call("static_model_missing")):
		return _advance_plan(ACTION_ADVANCE_WITHOUT_MATERIALIZATION, true)
	return _wait_plan(ACTION_WAIT_FOR_STATIC_MESH)


func _wait_plan(action: StringName) -> Dictionary:
	return {
		"action": action,
		"rotate_queue": true,
		"increment_batch_serial": false,
	}


func _advance_plan(action: StringName, increment_batch_serial: bool) -> Dictionary:
	return {
		"action": action,
		"rotate_queue": false,
		"increment_batch_serial": increment_batch_serial,
	}
