"""Verify POST /api/proposals/generate spawns dispatch_cli.py with correct argv
and returns 202 immediately."""
from __future__ import annotations

import asyncio
from unittest.mock import patch

import pytest
from httpx import ASGITransport, AsyncClient

from recoil.api.main import app


class _FakeProc:
    def __init__(self) -> None:
        self.pid = 99999
        self.stdout = asyncio.StreamReader()
        self.stderr = asyncio.StreamReader()
        self.stdout.feed_eof()
        self.stderr.feed_eof()

    async def wait(self) -> int:
        return 0


@pytest.mark.asyncio
async def test_generate_returns_202_and_spawns_dispatch_cli():
    fake_proc = _FakeProc()

    async def fake_create_subprocess_exec(*argv, **kwargs):
        fake_create_subprocess_exec.argv = argv
        return fake_proc

    fake_create_subprocess_exec.argv = ()

    with patch(
        "recoil.api.generation_routes.asyncio.create_subprocess_exec",
        side_effect=fake_create_subprocess_exec,
    ):
        transport = ASGITransport(app=app)
        async with AsyncClient(transport=transport, base_url="http://test") as client:
            r = await client.post(
                "/api/proposals/generate",
                json={
                    "project": "tartarus",
                    "episode": 1,
                    "dryRun": True,
                    "modality": "video_i2v",
                },
            )
            assert r.status_code == 202, r.text
            body = r.json()
            assert body["pid"] == 99999
            assert body["scope"] == "engine/generation"
            assert body["proposalId"].startswith("gen_")

    argv = fake_create_subprocess_exec.argv
    assert "dispatch_cli.py" in str(argv[1]), (
        f"Expected dispatch_cli.py in argv[1], got {argv}"
    )
    assert "--project" in argv and "tartarus" in argv
    assert "--dry-run" in argv
