"""Tests for the durable Campaign creation lifecycle seam."""

import pytest
from agenteval.evaluation.campaign_lifecycle import CampaignCreateError, create_campaign
from agenteval.models import CampaignPlanEntry, CampaignStatus, Case, Scenario
from agenteval.storage.repository import CampaignRepository, ScenarioRepository, TargetRepository

from tests.unit.test_repository import _make_target


def test_create_campaign_commits_running_before_launch(db_session):
    TargetRepository(db_session).create(_make_target())
    ScenarioRepository(db_session).create(Scenario(id="s-1", name="scenario", cases=[Case(id="c-1", messages=["hi"])]))
    launched: list[str] = []

    def launch(campaign_id):
        launched.append(campaign_id)
        assert CampaignRepository(db_session).get(campaign_id).status is CampaignStatus.RUNNING

    campaign = create_campaign(
        db_session,
        name="campaign",
        target_id="t-1",
        window_seconds=60,
        time_scale=1,
        plan=[CampaignPlanEntry(scenario_id="s-1", offset_seconds=0, count=1)],
        launch=launch,
    )

    assert campaign.status is CampaignStatus.RUNNING
    assert campaign.started_at is not None
    assert launched == [campaign.id]


def test_create_campaign_launch_failure_leaves_durable_row(db_session):
    TargetRepository(db_session).create(_make_target())
    ScenarioRepository(db_session).create(Scenario(id="s-1", name="scenario", cases=[Case(id="c-1", messages=["hi"])]))

    def launch(_campaign_id):
        raise RuntimeError("scheduler unavailable")

    with pytest.raises(RuntimeError):
        create_campaign(
            db_session,
            name="campaign",
            target_id="t-1",
            window_seconds=60,
            time_scale=1,
            plan=[CampaignPlanEntry(scenario_id="s-1", offset_seconds=0, count=1)],
            launch=launch,
        )

    rows = CampaignRepository(db_session).list_all()
    assert len(rows) == 1
    assert rows[0].status is CampaignStatus.RUNNING


def test_create_campaign_rejects_invalid_references_without_writing(db_session):
    with pytest.raises(CampaignCreateError) as exc:
        create_campaign(
            db_session,
            name="campaign",
            target_id="missing",
            window_seconds=60,
            time_scale=1,
            plan=[CampaignPlanEntry(scenario_id="s-1", offset_seconds=0, count=1)],
        )

    assert exc.value.status_code == 404
    assert CampaignRepository(db_session).list_all() == []
