"""ProofWarden's ``console_launch`` glue — the consumer side of the mgf-uitest-web contract.

The harness (``mgf-uitest-web``) ships its fixtures via a ``pytest11`` entry point, so
installing ``.[dev]`` is all it takes to get ``console``, ``viewport``, ``console_port``
and friends. The one thing the harness cannot know is **how to launch this console** —
that is what this fixture supplies. It builds a deterministic synthetic project (a test
catalog + one run record — plain-JSON mirrors of this package's own structures) and
launches the console against it.

Why the specs live here and not in the harness: the console owns its own UI gate. The
harness stays console-free (it is proven against a stdlib static server), and each
console's specs sit next to the code they gate, so a change to ProofWarden's chrome is
caught by ProofWarden's own CI.

ProofWarden's ``proofwarden`` CLI hardcodes port 8789, so we launch the app
directly via ``python -c create_app()`` to bind the harness-chosen ephemeral port.
No warden is started: the read-only views (Catalog / History / CI) render from the
project's ``generated/`` state, and Running renders its fail-closed ribbon (200,
never a 500) — which is itself a "no broken states" guarantee worth testing.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path
from typing import Any

import pytest
from mgf.uitest_web import ConsoleLaunch

SLUG = "demo"
_FILE = "tests/test_demo.py"
_NODE_ONE = f"{_FILE}::test_one"
_NODE_TWO = f"{_FILE}::test_two"

# Launch the console on the harness-chosen port (the CLI can't take a port).
_LAUNCH = (
    "import uvicorn; from mgf.test_web.web._app import create_app; "
    "uvicorn.run(create_app(), host='127.0.0.1', port={port})"
)


def _test_entry(node_id: str) -> dict[str, Any]:
    return {
        "id": node_id,
        "label": node_id.split("::", 1)[1],
        "runner": "pytest",
        "independent": False,
        "tags": [],
        "last_status": "unknown",
        "config": {},
        "config_schema": [],
    }


def _catalog(project: str) -> dict[str, Any]:
    tests = [_test_entry(_NODE_ONE), _test_entry(_NODE_TWO)]
    return {
        "schema_version": "0.1",
        "kind": "test_catalog",
        "project": project,
        "runners": [{"id": "pytest", "cmd": "pytest", "enumerate": "pytest --collect-only -q"}],
        "categories": [
            {
                "id": "tests",
                "label": "tests",
                "groups": [{"id": _FILE, "label": "test_demo.py", "tests": tests}],
            }
        ],
    }


def _run_record(project: str) -> dict[str, Any]:
    return {
        "schema_version": "0.1",
        "kind": "test_run_record",
        "run_id": "run_hist01",
        "project": project,
        "test_id": _NODE_ONE,
        "result": "pass",
        "started_at": "2026-06-29T10:00:00Z",
        "duration_s": 2,
        "origin": "ci",
        "who": "woodpecker",
        "effective_config": {"seed": 7},
        "config_digest": "sha256:abc",
        "lease": {"acquired_at": "2026-06-29T10:00:00Z", "heartbeats": 1, "reclaimed": False},
        "audit": [
            {"ts": "2026-06-29T10:00:00Z", "event": "lease_acquired"},
            {"ts": "2026-06-29T10:00:02Z", "event": "lease_released"},
        ],
    }


def _build_project(root: Path, project: str) -> Path:
    gen = root / "fed-resources" / "generated"
    (gen / "runs").mkdir(parents=True, exist_ok=True)
    (gen / "test_catalog.json").write_text(
        json.dumps(_catalog(project), indent=2) + "\n", encoding="utf-8"
    )
    (gen / "runs" / "run_hist01.json").write_text(
        json.dumps(_run_record(project), indent=2) + "\n", encoding="utf-8"
    )
    return root


@pytest.fixture
def console_launch(tmp_path: Path, console_port: int) -> ConsoleLaunch:
    """Consumer glue: build a synthetic project and launch this console on it.

    Launched with ``sys.executable`` — the interpreter already running the suite — so
    the console under test is always THIS checkout: no PATH lookup, no venv guessing,
    and nothing to keep in sync with a developer's machine layout.
    """
    project = _build_project(tmp_path / SLUG, SLUG)
    return ConsoleLaunch(
        command=[sys.executable, "-c", _LAUNCH.format(port=console_port)],
        env={"MGF_TEST_WEB_ROOTS": str(project)},
        ready_path="/",
        name="proofwarden",
    )
