"""
Module: sandbox.connection
Description: Resolve sandbox connection info from pidfile sidecar or explicit URL.

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

See Also:
    - docs/cli/agent-integration.md
"""

from __future__ import annotations

import json
import logging
import os
from pathlib import Path
from typing import Any

logger = logging.getLogger(__name__)

DEFAULT_PIDFILE = Path.home() / ".huitzo" / "sandbox.pid"
SIDECAR_SUFFIX = ".json"


def _sidecar_path(pidfile: Path) -> Path:
    """Return the sidecar JSON path for a given pidfile."""
    return pidfile.with_suffix(SIDECAR_SUFFIX)


def write_sidecar(pidfile: Path, url: str, token: str | None, commands: int) -> None:
    """Write connection info to the sidecar JSON file next to the pidfile."""
    sidecar = _sidecar_path(pidfile)
    sidecar.parent.mkdir(parents=True, exist_ok=True)
    data = {"url": url, "token": token, "commands": commands, "pid": os.getpid()}
    if os.name != "nt":
        fd = os.open(str(sidecar), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
        with os.fdopen(fd, "w") as f:
            json.dump(data, f)
    else:
        with open(sidecar, "w") as f:
            json.dump(data, f)


def read_sidecar(pidfile: Path) -> dict[str, Any] | None:
    """Read connection info from the sidecar JSON file. Returns None if missing/corrupt."""
    sidecar = _sidecar_path(pidfile)
    if not sidecar.exists():
        return None
    try:
        with open(sidecar) as f:
            data: dict[str, Any] = json.load(f)
            return data
    except (json.JSONDecodeError, OSError):
        logger.debug("Failed to read sidecar %s", sidecar)
        return None


def cleanup_sidecar(pidfile: Path) -> None:
    """Remove the sidecar JSON file."""
    sidecar = _sidecar_path(pidfile)
    if sidecar.exists():
        try:
            sidecar.unlink()
        except OSError:
            pass


def resolve_sandbox(
    sandbox_url: str | None = None,
    sandbox_token: str | None = None,
    pidfile: Path | None = None,
) -> tuple[str, str | None]:
    """Resolve how to connect to a sandbox.

    Priority:
    1. Explicit ``--sandbox-url`` (and optional ``--sandbox-token``)
    2. Sidecar JSON from pidfile (written by ``sandbox start --background``)
    3. Raise RuntimeError if nothing found

    Returns:
        (base_url, auth_token)
    """
    if sandbox_url:
        return sandbox_url, sandbox_token

    pf = pidfile or DEFAULT_PIDFILE
    info = read_sidecar(pf)
    if info and "url" in info:
        return info["url"], info.get("token")

    raise RuntimeError(
        "No running sandbox found. Start one with 'huitzo sandbox start' or provide --sandbox-url."
    )
