"""Tests for the trace logging system."""

import pytest

from agent_scout.db.database import Database
from agent_scout.db.models import Task
from agent_scout.events import Event, EventBus, EventType
from agent_scout.logging.tracer import Tracer


@pytest.fixture
async def setup(tmp_path):
    db = Database(str(tmp_path / "test.db"))
    await db.connect()
    bus = EventBus()
    tracer = Tracer(bus, db)
    # Create a task for FK compliance
    await db.create_task(Task(id="task-1", description="Test"))
    yield bus, db, tracer
    tracer.stop()
    await db.close()


async def test_tracer_persists_events(setup):
    bus, db, tracer = setup

    await bus.emit(
        Event(
            event_type=EventType.THOUGHT,
            data={"text": "Thinking about flights"},
            task_id="task-1",
        )
    )

    traces = await tracer.get_task_traces("task-1")
    assert len(traces) == 1
    assert traces[0].event_type == "thought"
    assert traces[0].data["text"] == "Thinking about flights"


async def test_tracer_captures_multiple_event_types(setup):
    bus, db, tracer = setup

    await bus.emit(
        Event(
            event_type=EventType.THOUGHT,
            data={"text": "thinking"},
            task_id="task-1",
        )
    )
    await bus.emit(
        Event(
            event_type=EventType.TOOL_CALL_START,
            data={"tool": "web_search"},
            task_id="task-1",
        )
    )
    await bus.emit(
        Event(
            event_type=EventType.TOOL_CALL_END,
            data={"tool": "web_search", "result": "found 5"},
            task_id="task-1",
        )
    )

    all_traces = await tracer.get_task_traces("task-1")
    assert len(all_traces) == 3

    tool_traces = await tracer.get_task_traces("task-1", event_type="tool_call_start")
    assert len(tool_traces) == 1


async def test_tracer_preserves_parent_id(setup):
    bus, db, tracer = setup

    parent_event = Event(
        event_type=EventType.THOUGHT,
        data={"text": "parent"},
        task_id="task-1",
    )
    await bus.emit(parent_event)

    child_event = Event(
        event_type=EventType.ACTION,
        data={"type": "tool_call"},
        task_id="task-1",
        parent_event_id=parent_event.event_id,
    )
    await bus.emit(child_event)

    traces = await tracer.get_task_traces("task-1")
    child_trace = [t for t in traces if t.event_type == "action"][0]
    assert child_trace.parent_id == parent_event.event_id


async def test_tracer_disable(setup):
    bus, db, tracer = setup

    tracer.disable()
    await bus.emit(
        Event(
            event_type=EventType.THOUGHT,
            data={"text": "should not be stored"},
            task_id="task-1",
        )
    )

    traces = await tracer.get_task_traces("task-1")
    assert len(traces) == 0

    tracer.enable()
    await bus.emit(
        Event(
            event_type=EventType.THOUGHT,
            data={"text": "should be stored"},
            task_id="task-1",
        )
    )

    traces = await tracer.get_task_traces("task-1")
    assert len(traces) == 1
