"""Tests for strict live stream property evaluation."""

import asyncio
import json

import httpx
import pytest
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from live import LiveLimits, run_live_scenario
from scenario import Scenario
from wire import validate_event


def test_live_scenario_accepts_a_valid_property_stream() -> None:
    async def run() -> None:
        app = FastAPI()

        @app.post("/api/recommendations")
        async def recommendations() -> StreamingResponse:
            events = [
                {
                    "type": "metadata",
                    "request_id": "request",
                    "intent_summary": "Calm music for coding with a familiar discovery mix.",
                    "candidate_count": 10,
                },
                {
                    "type": "track",
                    "rank": 1,
                    "track": {
                        "id": "track",
                        "uri": "spotify:track:track",
                        "title": "Track",
                        "artists": ["Artist"],
                        "album_name": "Album",
                        "album_art_url": None,
                        "external_url": None,
                    },
                    "justification": "A focused fit.",
                },
                {"type": "done", "track_count": 1, "total_ms": 1},
            ]
            body = "".join(json.dumps(event) + "\n" for event in events)
            return StreamingResponse(iter((body,)), media_type="application/x-ndjson")

        transport = httpx.ASGITransport(app=app)
        async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
            result = await run_live_scenario(
                client,
                Scenario(
                    "focus-coding",
                    "Focus while coding",
                    "calm coding music",
                    {"activity": "coding", "familiarity": "mix"},
                ),
                LiveLimits(1, 1, 1, 1_000, 1_000),
            )

        assert result.passed
        assert result.checks["event_order"]
        assert result.checks["done_track_count"]

    asyncio.run(run())


def test_wire_validation_rejects_extra_fields() -> None:
    line = json.dumps(
        {
            "type": "done",
            "track_count": 1,
            "total_ms": 1,
            "unexpected": True,
        }
    )

    with pytest.raises(ValueError, match="fields do not match"):
        validate_event(line)
