"""Tests for delayed campaign execution via Chronos."""
from __future__ import annotations

import asyncio

import pytest

from logos_adk.agent import Agent
from logos_adk.chronos import Chronos
from logos_adk.event_bus import SQLiteEventBus
from logos_adk.providers.mock import MockProvider
from logos_adk.team import Team
from logos_adk.types import Response, Usage


@pytest.mark.asyncio
async def test_chronos_processes_due_scheduled_event_after_restart(tmp_path):
    db_path = tmp_path / "event_bus.db"

    async def handle_ctr(event):
        return {"report": f"ctr::{event.payload['ad_id']}"}

    analyst_before = Agent("analyst", model="mock")
    team_before = Team(
        "growth",
        agents=[analyst_before],
        event_bus=SQLiteEventBus(str(db_path)),
        topic_policy={"analyst": ["check_ctr", "ctr_report"]},
    )
    team_before.subscribe("analyst", "check_ctr", handler=handle_ctr, publish_to="ctr_report")
    team_before.schedule_event(
        "analyst",
        "check_ctr",
        {"ad_id": "ad-42"},
        campaign_id="campaign-ctr",
        correlation_id="corr-ctr",
        run_id="run-ctr",
        delay_seconds=0.05,
    )

    analyst_after = Agent("analyst", model="mock")
    team_after = Team(
        "growth",
        agents=[analyst_after],
        event_bus=SQLiteEventBus(str(db_path)),
        topic_policy={"analyst": ["check_ctr", "ctr_report"]},
    )
    team_after.subscribe("analyst", "check_ctr", handler=handle_ctr, publish_to="ctr_report")
    chronos = Chronos(team_after, poll_interval_seconds=0.01)

    await asyncio.sleep(0.06)
    await chronos.run_once()

    state = team_after.campaign_state("campaign-ctr")
    assert state.total_events == 2
    assert state.completed_events == 1
    report_events = team_after.event_bus().list_events(topic="ctr_report", campaign_id="campaign-ctr")
    assert len(report_events) == 1
    assert report_events[0].payload == {"report": "ctr::ad-42"}


@pytest.mark.asyncio
async def test_chronos_processes_due_scheduled_task_after_restart(tmp_path):
    db_path = tmp_path / "scheduled_tasks.db"

    analyst_before = Agent("analyst", model="mock")
    Team(
        "growth",
        agents=[analyst_before],
        event_bus=SQLiteEventBus(str(db_path)),
    )
    analyst_before.schedule_task(
        "check ctr for ad-42",
        delay_seconds=0.05,
        campaign_id="campaign-task",
        session_id="session-task",
    )

    provider_after = MockProvider(responses=[
        Response(content="ctr checked", tool_calls=[], usage=Usage(1, 1), raw={}),
    ])
    analyst_after = Agent("analyst", model=provider_after)
    team_after = Team(
        "growth",
        agents=[analyst_after],
        event_bus=SQLiteEventBus(str(db_path)),
    )
    chronos = Chronos(team_after, poll_interval_seconds=0.01)

    await asyncio.sleep(0.06)
    await chronos.run_once()

    state = team_after.campaign_state("campaign-task")
    assert state.total_events == 1
    assert state.completed_events == 1
    events = team_after.event_bus().list_events(
        topic="__scheduled_task__:analyst",
        campaign_id="campaign-task",
    )
    assert len(events) == 1
    assert events[0].status == "completed"
    assert len(provider_after.call_history) == 1
    messages = provider_after.call_history[0]["messages"]
    assert messages[-1].content == "check ctr for ad-42"
