from __future__ import annotations

from pathlib import Path

from beaver.engine.session import SessionManager
from beaver.memory.runs import RunMemoryStore, RunRecord
from beaver.services.process_service import SessionProcessProjector


def test_process_projection_maps_task_team_events(tmp_path: Path) -> None:
    session = SessionManager(tmp_path)
    run_store = RunMemoryStore(tmp_path / "memory" / "runs")
    run_store.append_run_record(
        RunRecord(
            run_id="sub-run",
            session_id="sub-session",
            task_id="task-1",
            attempt_index=1,
            task_text="sub task",
            started_at="2026-01-01T00:00:01+00:00",
            ended_at="2026-01-01T00:00:02+00:00",
            success=True,
            finish_reason="stop",
        )
    )
    run_store.append_run_record(
        RunRecord(
            run_id="main-run",
            session_id="web:test",
            task_id="task-1",
            attempt_index=1,
            task_text="main task",
            started_at="2026-01-01T00:00:03+00:00",
            ended_at="2026-01-01T00:00:04+00:00",
            success=True,
            finish_reason="stop",
        )
    )
    session.append_message(
        "web:test",
        role="system",
        event_type="task_execution_planned",
        event_payload={
            "task_id": "task-1",
            "attempt_index": 1,
            "plan_mode": "team",
            "strategy": "sequence",
            "node_ids": ["research"],
            "skill_queries": ["research workflow"],
            "selected_skill_names": ["research-workflow"],
            "skill_resolution_report": [
                {
                    "node_id": "research",
                    "skill_query": "research workflow",
                    "selected_skill_names": ["research-workflow"],
                    "ephemeral_guidance_id": None,
                    "ephemeral_guidance_name": None,
                    "ephemeral_used": False,
                    "reason": "matched published skill",
                }
            ],
            "reason": "needs research",
        },
        context_visible=False,
    )
    session.append_message(
        "web:test",
        role="system",
        event_type="task_team_run_completed",
        event_payload={
            "task_id": "task-1",
            "attempt_index": 1,
            "team_success": True,
            "team_run_ids": ["sub-run"],
            "node_results": [
                {
                    "node_id": "research",
                    "success": True,
                    "output_text": "evidence",
                    "run_id": "sub-run",
                    "skill_query": "research workflow",
                    "selected_skill_names": ["research-workflow"],
                    "ephemeral_skill_names": [],
                    "ephemeral_guidance_id": None,
                    "ephemeral_guidance_name": None,
                    "ephemeral_used": False,
                    "finish_reason": "stop",
                }
            ],
        },
        context_visible=False,
    )
    session.append_message(
        "web:test",
        role="system",
        event_type="task_synthesis_completed",
        event_payload={"task_id": "task-1", "attempt_index": 1, "main_run_id": "main-run"},
        context_visible=False,
    )
    session.append_message(
        "web:test",
        run_id="main-run",
        role="system",
        event_type="task_evidence_recorded",
        event_payload={
            "task_id": "task-1",
            "attempt_index": 1,
            "evidence_status": "recorded",
        },
        context_visible=False,
    )

    projection = SessionProcessProjector(session, run_store).project("web:test")

    run_ids = {run["run_id"] for run in projection["runs"]}
    assert "task:task-1:attempt:1" in run_ids
    assert "sub-run" in run_ids
    assert "main-run" in run_ids
    sub_run = next(run for run in projection["runs"] if run["run_id"] == "sub-run")
    assert sub_run["metadata"]["selected_skill_names"] == ["research-workflow"]
    assert sub_run["metadata"]["skill_query"] == "research workflow"
    assert sub_run["metadata"]["ephemeral_guidance_id"] is None
    assert any(event["actor_name"] == "Evidence" for event in projection["events"])
    assert any(run["session_id"] == "web:test" for run in projection["runs"])


def test_process_projection_exposes_ephemeral_guidance_artifacts(tmp_path: Path) -> None:
    session = SessionManager(tmp_path)
    run_store = RunMemoryStore(tmp_path / "memory" / "runs")
    run_store.append_run_record(
        RunRecord(
            run_id="sub-run",
            session_id="sub-session",
            task_id="task-1",
            attempt_index=1,
            task_text="sub task",
            started_at="2026-01-01T00:00:01+00:00",
            ended_at="2026-01-01T00:00:02+00:00",
            success=True,
            finish_reason="stop",
        )
    )
    session.append_message(
        "web:test",
        role="system",
        event_type="task_execution_planned",
        event_payload={
            "task_id": "task-1",
            "attempt_index": 1,
            "plan_mode": "team",
            "strategy": "sequence",
            "node_ids": ["research"],
            "ephemeral_guidance_ids": ["eg_123"],
            "skill_resolution_report": [
                {
                    "node_id": "research",
                    "skill_query": "research workflow",
                    "selected_skill_names": [],
                    "ephemeral_guidance_id": "eg_123",
                    "ephemeral_guidance_name": "research-workflow",
                    "ephemeral_used": True,
                    "reason": "generated ephemeral guidance",
                }
            ],
        },
        context_visible=False,
    )
    session.append_message(
        "web:test",
        role="system",
        event_type="task_team_run_completed",
        event_payload={
            "task_id": "task-1",
            "attempt_index": 1,
            "team_success": True,
            "team_run_ids": ["sub-run"],
            "node_results": [
                {
                    "node_id": "research",
                    "success": True,
                    "output_text": "evidence",
                    "run_id": "sub-run",
                    "skill_query": "research workflow",
                    "selected_skill_names": [],
                    "ephemeral_skill_names": ["ephemeral:research-workflow"],
                    "ephemeral_guidance_id": "eg_123",
                    "ephemeral_guidance_name": "research-workflow",
                    "ephemeral_used": True,
                    "finish_reason": "stop",
                }
            ],
        },
        context_visible=False,
    )

    projection = SessionProcessProjector(session, run_store).project("web:test")

    sub_run = next(run for run in projection["runs"] if run["run_id"] == "sub-run")
    assert sub_run["metadata"]["ephemeral_guidance_id"] == "eg_123"
    assert projection["artifacts"][0]["artifact_id"] == "sub-run:ephemeral-guidance:eg_123"
    assert projection["artifacts"][0]["metadata"]["ephemeral_guidance_name"] == "research-workflow"
