"""Layer 1:结构化 schema → Decision 转换的单元测试(无需 LLM)。"""

from genesis.runtime.brain_schema import (
    ActionDecisionOut, ActionSpec, DialogueDecisionOut, GoalUpdate, SpeechSpec,
    action_to_decision, dialogue_to_decision,
)


def test_full_action_maps_all_fields():
    out = ActionDecisionOut(
        scheme="去码头找证据", thought="得快点", intent="赶往码头",
        speech=SpeechSpec(to="顾长风", text="我们一起去码头"),
        gesture="压低声音",
        action=ActionSpec(kind="move", arg="码头"),
        minutes=8,
        goal_update=GoalUpdate(index=1, status="doing", note="出发"),
        goals_replan=["先到码头", "再搜船屋"],
    )
    d = action_to_decision(out, fallback_intent="x")
    assert d.scheme == "去码头找证据"
    assert d.speech_to == "顾长风" and d.speech == "我们一起去码头"
    assert d.action_kind == "move" and d.action_arg == "码头"
    assert d.minutes == 8.0
    assert d.goal_update == {"index": 1, "status": "doing", "note": "出发"}
    assert d.replan == ["先到码头", "再搜船屋"]


def test_action_nulls_become_empty():
    out = ActionDecisionOut(intent="")
    d = action_to_decision(out, fallback_intent="保命要紧")
    assert d.speech == "" and d.speech_to == ""
    assert d.action_kind == "" and d.action_arg == ""
    assert d.intent == "保命要紧"      # 空 intent 回退
    assert d.replan is None and d.goal_update is None
    assert d.empty                      # 无话无动作无想法 → 空决策


def test_minutes_clamped():
    assert action_to_decision(ActionDecisionOut(action=ActionSpec(kind="idle"), minutes=99),
                              fallback_intent="x").minutes == 10.0
    assert action_to_decision(ActionDecisionOut(action=ActionSpec(kind="idle"), minutes=0.1),
                              fallback_intent="x").minutes == 2.0


def test_replan_truncated_to_four():
    out = ActionDecisionOut(goals_replan=["a", "b", "c", "d", "e", "f"])
    d = action_to_decision(out, fallback_intent="x")
    assert d.replan == ["a", "b", "c", "d"]


def test_dialogue_mapping():
    out = DialogueDecisionOut(thought="他在套我", speech="我什么都不知道", gesture="后退半步", leave=True)
    d = dialogue_to_decision(out, dialogue_with="邵铭轩", fallback_intent="提防")
    assert d.speech == "我什么都不知道" and d.speech_to == "邵铭轩"
    assert d.leave_dialogue is True
    assert d.gesture == "后退半步"
    assert d.intent == "提防"
