"""
Module: _sandbox_serve
Description: Hidden internal command for running the sandbox in the foreground.
    Spawned by ``huitzo sandbox start --background``.

Implements:
    - docs/cli/reference.md#huitzo-sandbox
    - docs/cli/agent-integration.md#sandbox-lifecycle
"""

from __future__ import annotations

import json
import logging
import os
import signal
import sys
import threading
from pathlib import Path

import typer

from huitzo_cli.sandbox.connection import DEFAULT_PIDFILE, cleanup_sidecar, write_sidecar

logger = logging.getLogger(__name__)

sandbox_serve_app = typer.Typer(hidden=True)


@sandbox_serve_app.command("_sandbox-serve")
def sandbox_serve(
    port: int = typer.Option(8080, "--port"),
    no_tls: bool = typer.Option(False, "--no-tls"),
    use_platform: bool = typer.Option(False, "--use-platform"),
    pidfile: str = typer.Option(str(DEFAULT_PIDFILE), "--pidfile"),
    token: str | None = typer.Option(None, "--token"),
) -> None:
    """Internal: run sandbox in foreground (used by sandbox start --background)."""
    from huitzo_cli.sandbox.proxy import LocalSandbox

    # Prefer env var token over CLI arg (avoids /proc/pid/cmdline exposure)
    token = os.environ.get("_HUITZO_SANDBOX_TOKEN", token)

    pf = Path(pidfile)
    pf.parent.mkdir(parents=True, exist_ok=True)

    # Write PID file
    pid = os.getpid()
    if os.name != "nt":
        fd = os.open(str(pf), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
        with os.fdopen(fd, "w") as f:
            f.write(str(pid))
    else:
        with open(pf, "w") as f:
            f.write(str(pid))

    sandbox = LocalSandbox(auth_token=token, use_platform=use_platform)
    use_tls = not no_tls

    try:
        commands = sandbox.discover_commands()
        base_url = sandbox.start(port=port, use_tls=use_tls)
    except Exception as exc:
        logger.error("Sandbox startup failed: %s", exc)
        _cleanup(pf)
        sys.exit(1)

    # Write sidecar with connection info
    active_token = sandbox.auth_token or token
    write_sidecar(pf, base_url, active_token, len(commands))

    # Print machine-readable startup info to stdout (parent reads this)
    # Token is NOT included — read from sidecar file instead
    startup_info = {
        "url": base_url,
        "pid": pid,
        "commands": len(commands),
        "token_source": str(pf.with_suffix(".json")),
    }
    print(json.dumps(startup_info), flush=True)

    # Handle SIGTERM for clean shutdown
    stop_event = threading.Event()

    def _handle_sigterm(signum: int, frame: object) -> None:
        stop_event.set()

    signal.signal(signal.SIGTERM, _handle_sigterm)

    try:
        while not stop_event.wait(timeout=1):
            pass
    except KeyboardInterrupt:
        pass
    finally:
        sandbox.stop()
        _cleanup(pf)


def _cleanup(pidfile: Path) -> None:
    """Remove pidfile and sidecar."""
    if pidfile.exists():
        try:
            pidfile.unlink()
        except OSError:
            pass
    cleanup_sidecar(pidfile)


if __name__ == "__main__":
    sandbox_serve_app()
