"""Smoke tests for scripts/ensure_staging_server.py.

The script is part of the v7.5.3 Write Safety Guard: Claude must run it
before announcing any preview URL to a user so the URL never 404s.
"""
import os
import socket
import subprocess
import sys
import time
from pathlib import Path

import pytest

PLUGIN_ROOT = Path(__file__).resolve().parents[1]
SCRIPT = PLUGIN_ROOT / "scripts" / "ensure_staging_server.py"


def _free_port():
    """Return an OS-assigned free TCP port; close socket immediately."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(("127.0.0.1", 0))
        return s.getsockname()[1]


def _kill_listener(port):
    """Best-effort kill of any process listening on the given port."""
    try:
        out = subprocess.run(
            ["lsof", "-ti", f":{port}"],
            capture_output=True, text=True, timeout=5,
        )
        for pid in out.stdout.split():
            try:
                os.kill(int(pid), 15)
            except (ProcessLookupError, ValueError):
                pass
        time.sleep(0.5)
    except FileNotFoundError:
        pass  # lsof not available in CI; rely on test fixtures


@pytest.fixture
def port():
    p = _free_port()
    yield p
    _kill_listener(p)


def test_launches_when_not_running(port):
    """First call launches the server and prints the canonical base URL."""
    _kill_listener(port)
    r = subprocess.run(
        [sys.executable, str(SCRIPT), "--port", str(port), "--timeout", "8"],
        capture_output=True, text=True, timeout=15,
    )
    assert r.returncode == 0, f"launch failed: {r.stderr}"
    assert r.stdout.strip() == f"http://127.0.0.1:{port}"


def test_idempotent_when_already_running(port):
    """Second call returns immediately with the same URL."""
    subprocess.run(
        [sys.executable, str(SCRIPT), "--port", str(port), "--timeout", "8"],
        capture_output=True, text=True, timeout=15,
    )
    t0 = time.monotonic()
    r = subprocess.run(
        [sys.executable, str(SCRIPT), "--port", str(port)],
        capture_output=True, text=True, timeout=5,
    )
    elapsed = time.monotonic() - t0
    assert r.returncode == 0
    assert r.stdout.strip() == f"http://127.0.0.1:{port}"
    assert elapsed < 2.0, f"idempotent call too slow: {elapsed:.2f}s"


def test_uses_loopback_address(port):
    """The script must announce 127.0.0.1, not localhost."""
    r = subprocess.run(
        [sys.executable, str(SCRIPT), "--port", str(port), "--timeout", "8"],
        capture_output=True, text=True, timeout=15,
    )
    assert "127.0.0.1" in r.stdout
    assert "localhost" not in r.stdout
