#!/usr/bin/env python3
"""Idempotently ensure the staging preview server is running on 127.0.0.1:8111.

Use this BEFORE announcing any preview URL to a user. The script:
  - returns 0 + prints the base URL if a server is already bound to :8111
  - launches scripts/staging_server.py in the background, waits for it to bind,
    then returns 0 + prints the base URL
  - returns non-zero on failure (port held by something else, launch failed)

Per CLAUDE.md §Write Safety Guard step 2: never announce a URL that will fail.
This script removes that failure mode.

Usage:
    python3 scripts/ensure_staging_server.py [--port 8111]
"""

import argparse
import os
import socket
import subprocess
import sys
import time
from pathlib import Path

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


def _is_bound(host: str, port: int) -> bool:
    """Return True if something is already accepting connections on host:port."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(0.25)
        try:
            s.connect((host, port))
            return True
        except (ConnectionRefusedError, socket.timeout, OSError):
            return False


def _launch(port: int) -> subprocess.Popen:
    """Start staging_server.py in the background, detached from the caller."""
    log_path = Path("/tmp") / f"asucb-staging-{port}.log"
    log_fh = open(log_path, "a")
    return subprocess.Popen(
        [sys.executable, str(SERVER_SCRIPT), "--port", str(port)],
        stdout=log_fh,
        stderr=subprocess.STDOUT,
        stdin=subprocess.DEVNULL,
        start_new_session=True,
        cwd=str(PLUGIN_ROOT),
    )


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--port", type=int, default=8111)
    parser.add_argument("--timeout", type=float, default=6.0,
                        help="Seconds to wait for server to bind after launch")
    args = parser.parse_args()

    host = "127.0.0.1"
    base_url = f"http://{host}:{args.port}"

    if _is_bound(host, args.port):
        print(base_url)
        return 0

    _launch(args.port)
    deadline = time.monotonic() + args.timeout
    while time.monotonic() < deadline:
        if _is_bound(host, args.port):
            print(base_url)
            return 0
        time.sleep(0.2)

    print(f"ERROR: staging server did not bind to {host}:{args.port} within "
          f"{args.timeout}s. Check /tmp/asucb-staging-{args.port}.log.",
          file=sys.stderr)
    return 2


if __name__ == "__main__":
    sys.exit(main())
