from codex_autorunner.core.ports.run_event import (
    RUN_EVENT_DELTA_TYPE_ASSISTANT_MESSAGE,
    RUN_EVENT_DELTA_TYPE_LOG_LINE,
    Completed,
    OutputDelta,
    RunNotice,
    ToolCall,
)
from codex_autorunner.integrations.chat.managed_thread_progress import (
    ProgressRuntimeState,
    apply_run_event_to_progress_tracker,
)
from codex_autorunner.integrations.chat.progress_primitives import TurnProgressTracker


def _tracker() -> TurnProgressTracker:
    return TurnProgressTracker(
        started_at=0.0,
        agent="codex",
        model="default",
        label="working",
        max_actions=12,
        max_output_chars=400,
    )


def test_apply_run_event_to_progress_tracker_records_tool_calls() -> None:
    tracker = _tracker()

    outcome = apply_run_event_to_progress_tracker(
        tracker,
        ToolCall(timestamp="2026-03-15T00:00:00Z", tool_name="exec", tool_input={}),
        runtime_state=ProgressRuntimeState(),
    )

    assert outcome.changed is True
    assert outcome.terminal is False
    assert tracker.transient_action is not None
    assert tracker.transient_action.label == "tool"
    assert tracker.transient_action.text == "exec"


def test_apply_run_event_to_progress_tracker_updates_log_line_output() -> None:
    tracker = _tracker()

    outcome = apply_run_event_to_progress_tracker(
        tracker,
        OutputDelta(
            timestamp="2026-03-15T00:00:00Z",
            content="Tokens used: 10",
            delta_type=RUN_EVENT_DELTA_TYPE_LOG_LINE,
        ),
        runtime_state=ProgressRuntimeState(),
    )

    assert outcome.changed is True
    assert tracker.actions[-1].label == "output"
    assert tracker.actions[-1].text == "Tokens used: 10"
    assert tracker.actions[-1].item_id == "opencode:token-usage"


def test_apply_run_event_to_progress_tracker_finalizes_completed_turn() -> None:
    tracker = _tracker()
    runtime_state = ProgressRuntimeState()
    apply_run_event_to_progress_tracker(
        tracker,
        OutputDelta(
            timestamp="2026-03-15T00:00:00Z",
            content="intermediate text",
            delta_type=RUN_EVENT_DELTA_TYPE_ASSISTANT_MESSAGE,
        ),
        runtime_state=runtime_state,
    )

    outcome = apply_run_event_to_progress_tracker(
        tracker,
        Completed(
            timestamp="2026-03-15T00:00:01Z",
            final_message="final answer",
        ),
        runtime_state=runtime_state,
    )

    assert outcome.changed is True
    assert outcome.terminal is True
    assert outcome.render_mode == "final"
    assert tracker.label == "done"
    assert runtime_state.final_message == "final answer"


def test_apply_run_event_to_progress_tracker_marks_interrupts_terminal() -> None:
    tracker = _tracker()

    outcome = apply_run_event_to_progress_tracker(
        tracker,
        RunNotice(
            timestamp="2026-03-15T00:00:00Z",
            kind="interrupted",
            message="Turn interrupted",
        ),
        runtime_state=ProgressRuntimeState(),
    )

    assert outcome.changed is True
    assert outcome.force is True
    assert outcome.terminal is True
    assert tracker.label == "cancelled"
