"""E2E test fixtures: live uvicorn server for Playwright."""
from __future__ import annotations

import os
import socket
import threading
import time

import httpx
import pytest
import uvicorn


def _free_port() -> int:
    with socket.socket() as s:
        s.bind(("127.0.0.1", 0))
        return s.getsockname()[1]


@pytest.fixture(scope="session")
def live_server(tmp_path_factory):
    """Start the FastAPI app on a random port in a background thread."""
    # Isolated data dir for E2E session
    data_dir = tmp_path_factory.mktemp("imptune_e2e_data")

    # Patch config module so the app uses the temp dir
    import imptune.config as cfg

    cfg.DATA_DIR = str(data_dir)
    cfg.DB_PATH = str(data_dir / "imptune.db")
    cfg.DRIVERS_DIR = str(data_dir / "drivers")
    cfg.ICONS_DIR = str(data_dir / "icons")

    os.makedirs(cfg.DRIVERS_DIR, exist_ok=True)
    os.makedirs(cfg.ICONS_DIR, exist_ok=True)

    # Also set env var so lifespan handler picks up correct dirs
    os.environ["DATA_DIR"] = str(data_dir)

    # Initialize DB against the tmp dir
    from imptune.db.database import init_db

    init_db()

    from imptune.main import app

    port = _free_port()
    config = uvicorn.Config(app, host="127.0.0.1", port=port, log_level="error")
    server = uvicorn.Server(config)
    thread = threading.Thread(target=server.run, daemon=True)
    thread.start()

    base_url = f"http://127.0.0.1:{port}"
    # Readiness poll via /health (up to 5 s)
    deadline = time.time() + 5.0
    while time.time() < deadline:
        try:
            r = httpx.get(f"{base_url}/health", timeout=0.5)
            if r.status_code == 200:
                break
        except Exception:
            pass
        time.sleep(0.1)
    else:
        raise RuntimeError("live_server did not become ready within 5 s")

    yield base_url

    server.should_exit = True
    thread.join(timeout=2.0)
