"""
Example: run sunwaee CLI commands inside a per-user Docker container.

Flow:
  1. Create (or reuse) a container named user-{uuid} with sunwaee installed
  2. Start it if not already running
  3. Exec a sunwaee command and capture the JSON output
  4. Display the result
"""

import json
import subprocess
import time
import uuid

# ---------------------------------------------------------------------------
# Config
# ---------------------------------------------------------------------------

IMAGE = "python:3.12-slim"
USER_ID =  "12345"
CONTAINER_NAME = f"user-{USER_ID}"

# Directory inside the container where user data lives.
# In production, bind-mount a persistent host volume here.
WORKSPACES_DIR = "/root/sunwaee/workspaces"


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def run(cmd: list[str], check: bool = True) -> subprocess.CompletedProcess:
    result = subprocess.run(cmd, capture_output=True, text=True)
    if check and result.returncode != 0:
        raise RuntimeError(
            f"Command failed: {' '.join(cmd)}\n"
            f"stdout: {result.stdout.strip()}\n"
            f"stderr: {result.stderr.strip()}"
        )
    return result


def container_exists(name: str) -> bool:
    result = run(["docker", "ps", "-a", "--filter", f"name=^{name}$", "--format", "{{.Names}}"], check=False)
    return name in result.stdout.splitlines()


def container_running(name: str) -> bool:
    result = run(["docker", "ps", "--filter", f"name=^{name}$", "--format", "{{.Names}}"], check=False)
    return name in result.stdout.splitlines()


def _timed(label: str, fn):
    t0 = time.perf_counter()
    result = fn()
    ms = (time.perf_counter() - t0) * 1000
    print(f"  [{ms:.0f}ms] {label}")
    return result


def create_container(name: str) -> None:
    """Create a persistent container with sunwaee installed."""
    print(f"Creating container {name} ...")
    _timed("docker run", lambda: run([
        "docker", "run",
        "--name", name,
        "--detach",
        "--entrypoint", "tail",
        "--env", "SUNWAEE_CALLER=api",
        "--env", f"SUNWAEE_WORKSPACES_DIR={WORKSPACES_DIR}",
        IMAGE,
        "-f", "/dev/null",
    ]))
    _timed("pip install sunwaee", lambda: run(["docker", "exec", name, "pip", "install", "--quiet", "sunwaee"]))
    _timed("sunwaee init", lambda: run(["docker", "exec", name, "sunwaee", "init"]))


def start_container(name: str) -> None:
    print(f"Starting container {name} ...")
    run(["docker", "start", name])


def exec_command(name: str, sunwaee_args: list[str]) -> dict:
    """Run a sunwaee command and return the parsed JSON response."""
    result = run(
        ["docker", "exec", name, "sunwaee"] + sunwaee_args,
        check=False,
    )
    if result.returncode != 0:
        # Try to parse error JSON; fall back to raw stderr.
        try:
            return json.loads(result.stdout)
        except json.JSONDecodeError:
            return {"ok": False, "error": result.stderr.strip()}
    return json.loads(result.stdout)


# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------

def main() -> None:
    # 1. Ensure container exists and is running.
    if not container_exists(CONTAINER_NAME):
        create_container(CONTAINER_NAME)
    elif not container_running(CONTAINER_NAME):
        start_container(CONTAINER_NAME)
    else:
        print(f"Container {CONTAINER_NAME} already running.")

    # 2. Run some commands and display results.
    commands = [
        # Create a task
        ["task", "create", "--title", "Buy groceries", "--priority", "low"],
        # Create a note
        ["note", "create", "--title", "Hello from Docker", "--body", "This note was created via docker exec."],
        # List tasks (JSON array)
        ["task", "list"],
        # List notes
        ["note", "list"],
    ]

    for args in commands:
        print(f"\n$ sunwaee {' '.join(args)}")
        t0 = time.perf_counter()
        response = exec_command(CONTAINER_NAME, args)
        ms = (time.perf_counter() - t0) * 1000
        print(f"  [{ms:.0f}ms]")
        print(json.dumps(response, indent=2))

    print(f"\nDone. Container '{CONTAINER_NAME}' is still running for subsequent calls.")
    print(f"To stop it:   docker stop {CONTAINER_NAME}")
    print(f"To remove it: docker rm -f {CONTAINER_NAME}")


if __name__ == "__main__":
    main()
