"""Mom sandbox configuration — parse and validate sandbox arguments."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Literal, Union


@dataclass
class HostSandbox:
    """Host sandbox (no isolation)."""

    type: Literal["host"] = "host"


@dataclass
class DockerSandbox:
    """Docker sandbox."""

    type: Literal["docker"] = "docker"
    container: str = ""


SandboxConfig = Union[HostSandbox, DockerSandbox]


def parse_sandbox_arg(value: str) -> SandboxConfig:
    """Parse a sandbox argument string.

    Args:
        value: "host" or "docker:<container-name>"

    Returns:
        SandboxConfig instance.

    Raises:
        ValueError: If the value is invalid.
    """
    if value == "host":
        return HostSandbox()

    if value.startswith("docker:"):
        container = value[len("docker:"):]
        if not container:
            raise ValueError("docker sandbox requires container name (e.g., docker:mom-sandbox)")
        return DockerSandbox(container=container)

    raise ValueError(f"Invalid sandbox type '{value}'. Use 'host' or 'docker:<container-name>'")


async def validate_sandbox(config: SandboxConfig) -> None:
    """Validate that a sandbox configuration is usable.

    For host: no-op.
    For docker: checks docker binary and container status.

    Raises:
        RuntimeError: If validation fails.
    """
    if isinstance(config, HostSandbox):
        return

    import asyncio

    # Check docker is available
    try:
        proc = await asyncio.create_subprocess_exec(
            "docker", "--version",
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )
        await proc.communicate()
        if proc.returncode != 0:
            raise RuntimeError("Docker is not installed or not in PATH")
    except FileNotFoundError:
        raise RuntimeError("Docker is not installed or not in PATH")

    # Check container is running
    try:
        proc = await asyncio.create_subprocess_exec(
            "docker", "inspect", "-f", "{{.State.Running}}", config.container,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )
        stdout, _ = await proc.communicate()
        result = stdout.decode().strip()
        if result != "true":
            raise RuntimeError(
                f"Container '{config.container}' is not running. "
                f"Start it with: docker start {config.container}"
            )
    except FileNotFoundError:
        raise RuntimeError("Docker is not installed or not in PATH")
    except RuntimeError:
        raise
    except Exception:
        raise RuntimeError(
            f"Container '{config.container}' does not exist. "
            "Create it with: ./docker.sh create <data-dir>"
        )
