#!/usr/bin/env python3
from __future__ import annotations

import argparse
import datetime as dt
import hashlib
import json
import os
import plistlib
import secrets
import subprocess
import sys
import time
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path
from typing import Any


VERSION = "2026.08.29-codee-remote-browser-voice-v5"
REMOTE_API_BASE = str(os.getenv("CODEE_REMOTE_API_BASE") or "https://clients.codee.chat/api/remote").rstrip("/")
COMMAND_PRESETS = {
    "status": {
        "title": "Host Status",
        "purpose": "Show installed host, session, emergency-stop, and queue state.",
        "example": "python3 codee-remote-host.py status .",
    },
    "doctor": {
        "title": "Codee Doctor",
        "purpose": "Check local tools, sensitive files, manifests, and public routes.",
        "example": "python3 codee.py doctor .",
    },
    "heartbeat": {
        "title": "Heartbeat",
        "purpose": "Show a one-command pulse of folder health, proof, tasks, and next steps.",
        "example": "python3 codee.py heartbeat . --service codeeqr",
    },
    "scan": {
        "title": "Route Scan",
        "purpose": "Scan public routes and catch 404s before the owner promotes a link.",
        "example": "python3 codee.py browser-scan . --url https://clients.codee.chat/codee-chat.html",
    },
}
ALLOWLIST = set(COMMAND_PRESETS)
BLOCKED_ACTIONS = {
    "raw shell",
    "secret export",
    "destructive cleanup",
    "silent screen streaming",
    "owner credential access",
    "hidden background control",
}
TOOLBOX = [
    {"id": "pair", "title": "Pair Phone", "host_command": "python3 codee-remote-host.py pair . --write", "state": "foundation-live"},
    {"id": "session-start", "title": "Start Visible Session", "host_command": "python3 codee-remote-host.py session . --session-action start --write", "state": "foundation-live"},
    {"id": "session-stop", "title": "Stop Session", "host_command": "python3 codee-remote-host.py stop . --write", "state": "foundation-live"},
    {"id": "enqueue-heartbeat", "title": "Queue Heartbeat", "host_command": "python3 codee-remote-host.py enqueue . --command heartbeat --write", "state": "foundation-live"},
    {"id": "enqueue-doctor", "title": "Queue Doctor", "host_command": "python3 codee-remote-host.py enqueue . --command doctor --write", "state": "foundation-live"},
    {"id": "enqueue-status", "title": "Queue Status", "host_command": "python3 codee-remote-host.py enqueue . --command status --write", "state": "live"},
    {"id": "enqueue-scan", "title": "Queue Route Scan", "host_command": "python3 codee-remote-host.py enqueue . --command scan --write", "state": "live"},
    {"id": "proof", "title": "Export Proof Packet", "host_command": "python3 codee-remote-host.py proof . --write", "state": "foundation-live"},
    {"id": "audit", "title": "Audit Events", "host_command": "python3 codee-remote-host.py audit .", "state": "foundation-live"},
    {"id": "native-setup", "title": "Enable Native Input", "host_command": "python3 codee-remote-host.py native-setup . --enable", "state": "owner-opt-in-live"},
    {"id": "service-install", "title": "Install Background Host", "host_command": "python3 codee-remote-host.py service-install .", "state": "mac-live"},
]


def now() -> str:
    return dt.datetime.now(dt.timezone.utc).isoformat()


def write_json(path: Path, payload: dict[str, Any], *, force: bool = True) -> bool:
    path.parent.mkdir(parents=True, exist_ok=True)
    if path.exists() and not force:
        return False
    path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
    return True


def read_json(path: Path) -> dict[str, Any]:
    if not path.exists():
        return {}
    try:
        parsed = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    return parsed if isinstance(parsed, dict) else {}


def append_event(root: Path, event: str, payload: dict[str, Any] | None = None) -> Path:
    path = root / ".codee" / "remote-host" / "events.jsonl"
    path.parent.mkdir(parents=True, exist_ok=True)
    record = {
        "schema": "codee.remote-host.event.v1",
        "created_at": now(),
        "event": event,
        "host_version": VERSION,
        "payload": payload or {},
    }
    with path.open("a", encoding="utf-8") as handle:
        handle.write(json.dumps(record, sort_keys=True) + "\n")
    return path


def device_id(root: Path, device_name: str) -> str:
    seed = f"{root.resolve()}:{device_name}"
    return "cdev_" + hashlib.sha256(seed.encode("utf-8")).hexdigest()[:16]


def remote_dir(root: Path) -> Path:
    return root / ".codee" / "remote-host"


def state_path(root: Path) -> Path:
    return remote_dir(root) / "host-state.json"


def queue_path(root: Path) -> Path:
    return remote_dir(root) / "command-queue.json"


def pairing_path(root: Path) -> Path:
    return remote_dir(root) / "pairing.json"


def session_path(root: Path) -> Path:
    return remote_dir(root) / "session.json"


def proof_path(root: Path) -> Path:
    return remote_dir(root) / "latest-proof.json"


def cloud_session_path(root: Path) -> Path:
    return remote_dir(root) / "cloud-session.json"


def api_json(method: str, url: str, *, token: str = "", payload: dict[str, Any] | None = None) -> tuple[int, dict[str, Any]]:
    body = None if payload is None else json.dumps(payload).encode("utf-8")
    headers = {"Accept": "application/json"}
    if body is not None:
        headers["Content-Type"] = "application/json"
    if token:
        headers["Authorization"] = f"Bearer {token}"
    req = urllib.request.Request(url, data=body, headers=headers, method=method)
    try:
        with urllib.request.urlopen(req, timeout=30) as response:
            raw = response.read()
            return int(response.status), json.loads(raw.decode("utf-8")) if raw else {}
    except urllib.error.HTTPError as exc:
        raw = exc.read()
        try:
            parsed = json.loads(raw.decode("utf-8")) if raw else {}
        except Exception:
            parsed = {"ok": False, "error": f"http_{exc.code}"}
        return int(exc.code), parsed


def _cloud_session(root: Path) -> dict[str, Any]:
    return read_json(cloud_session_path(root))


def _find_codee_cli(root: Path) -> Path | None:
    candidates = [
        root / "codee.py",
        root / "tools" / "codee_cli.py",
        Path(__file__).resolve().with_name("codee-cli.py"),
    ]
    return next((path for path in candidates if path.is_file()), None)


def _execute_cloud_command(root: Path, command: str) -> dict[str, Any]:
    normalized = normalize_command(command)
    if normalized == "status":
        state = read_state(root)
        return {"ok": bool(state), "status": "completed", "command": normalized, "output": json.dumps(state, indent=2)[:12000]}
    cli = _find_codee_cli(root)
    if normalized not in {"doctor", "heartbeat", "scan"}:
        return {
            "ok": False,
            "status": "manual-approval-required",
            "command": normalized,
            "output": "This command is allowlisted for the viewer but requires local approval in the current host release.",
        }
    if not cli:
        return {"ok": False, "status": "missing-codee-cli", "command": normalized, "output": "Codee CLI was not found in this workspace."}
    argv = [sys.executable, str(cli)]
    if normalized == "doctor":
        argv.extend(["doctor", str(root)])
    elif normalized == "heartbeat":
        argv.extend(["heartbeat", str(root)])
    else:
        argv.extend(["browser-scan", str(root), "--url", "https://clients.codee.chat/codee-chat.html"])
    try:
        completed = subprocess.run(
            argv,
            cwd=str(root),
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            timeout=180,
            check=False,
        )
        return {
            "ok": completed.returncode == 0,
            "status": "completed" if completed.returncode == 0 else "failed",
            "command": normalized,
            "returncode": completed.returncode,
            "output": str(completed.stdout or "")[-12000:],
        }
    except subprocess.TimeoutExpired:
        return {"ok": False, "status": "timed-out", "command": normalized, "output": "Command exceeded the 180 second host limit."}


def _native_helper_path(root: Path) -> Path:
    return remote_dir(root) / "codee-remote-input"


def _native_input_enabled(root: Path) -> bool:
    return bool(read_state(root).get("native_input_enabled") and _native_helper_path(root).is_file())


def _execute_native_input(root: Path, payload: dict[str, Any]) -> dict[str, Any]:
    action = str(payload.get("action") or "").strip().lower()
    if sys.platform != "darwin" or not _native_input_enabled(root):
        return {"ok": False, "status": "native-input-locked", "action": action}
    argv = [str(_native_helper_path(root)), action]
    if action in {"move", "click", "double-click"}:
        argv.extend([str(float(payload.get("x") or 0)), str(float(payload.get("y") or 0)), str(payload.get("button") or "left")])
    elif action == "scroll":
        argv.extend([str(float(payload.get("dx") or 0)), str(float(payload.get("dy") or 0))])
    elif action == "key":
        argv.append(str(payload.get("key") or "")[:30])
    elif action == "text":
        value = str(payload.get("text") or "")[:300]
        if not value:
            return {"ok": False, "status": "empty-text", "action": action}
        try:
            for offset in range(0, len(value), 60):
                completed = subprocess.run([str(_native_helper_path(root)), "key", value[offset:offset + 60]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=3, check=False)
                if completed.returncode != 0:
                    return {"ok": False, "status": "failed", "action": action, "output": str(completed.stdout or "")[-1000:]}
            return {"ok": True, "status": "completed", "action": action, "character_count": len(value)}
        except Exception as exc:
            return {"ok": False, "status": "failed", "action": action, "output": str(exc)[:500]}
    else:
        return {"ok": False, "status": "invalid-input-action", "action": action}
    try:
        completed = subprocess.run(argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=3, check=False)
        return {"ok": completed.returncode == 0, "status": "completed" if completed.returncode == 0 else "failed", "action": action, "output": str(completed.stdout or "")[-1000:]}
    except Exception as exc:
        return {"ok": False, "status": "failed", "action": action, "output": str(exc)[:500]}


NATIVE_INPUT_SOURCE = r'''#include <ApplicationServices/ApplicationServices.h>
#include <CoreFoundation/CoreFoundation.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static double unit(const char *value) { double n = atof(value); return fmax(0.0, fmin(1.0, n)); }
static CGPoint point_for(const char *x, const char *y) {
  CGRect bounds = CGDisplayBounds(CGMainDisplayID());
  return CGPointMake(bounds.origin.x + unit(x) * bounds.size.width, bounds.origin.y + unit(y) * bounds.size.height);
}
static void post_mouse(CGEventType type, CGPoint point, CGMouseButton button) {
  CGEventRef event = CGEventCreateMouseEvent(NULL, type, point, button);
  if (event) { CGEventPost(kCGHIDEventTap, event); CFRelease(event); }
}
static void click_mouse(CGPoint point, CGMouseButton button, int clicks) {
  CGEventType downType=button==kCGMouseButtonRight?kCGEventRightMouseDown:kCGEventLeftMouseDown;
  CGEventType upType=button==kCGMouseButtonRight?kCGEventRightMouseUp:kCGEventLeftMouseUp;
  for(int i=1;i<=clicks;i++){CGEventRef down=CGEventCreateMouseEvent(NULL,downType,point,button);CGEventRef up=CGEventCreateMouseEvent(NULL,upType,point,button);if(down&&up){CGEventSetIntegerValueField(down,kCGMouseEventClickState,i);CGEventSetIntegerValueField(up,kCGMouseEventClickState,i);CGEventPost(kCGHIDEventTap,down);usleep(30000);CGEventPost(kCGHIDEventTap,up);}if(down)CFRelease(down);if(up)CFRelease(up);usleep(50000);}
}
static CGKeyCode special_code(const char *key) {
  if (!strcmp(key,"Enter")) return 36; if (!strcmp(key,"Backspace")) return 51;
  if (!strcmp(key,"Tab")) return 48; if (!strcmp(key,"Escape")) return 53;
  if (!strcmp(key,"ArrowLeft")) return 123; if (!strcmp(key,"ArrowRight")) return 124;
  if (!strcmp(key,"ArrowDown")) return 125; if (!strcmp(key,"ArrowUp")) return 126;
  if (!strcmp(key," ")) return 49; return UINT16_MAX;
}
int main(int argc, char **argv) {
  if (argc < 2 || !AXIsProcessTrusted()) return 2;
  if (!strcmp(argv[1],"move") && argc >= 4) post_mouse(kCGEventMouseMoved, point_for(argv[2],argv[3]), kCGMouseButtonLeft);
  else if ((!strcmp(argv[1],"click") || !strcmp(argv[1],"double-click")) && argc >= 4) { CGPoint p=point_for(argv[2],argv[3]); CGMouseButton b=(argc>=5&&!strcmp(argv[4],"right"))?kCGMouseButtonRight:kCGMouseButtonLeft; click_mouse(p,b,!strcmp(argv[1],"double-click")?2:1); }
  else if (!strcmp(argv[1],"scroll") && argc >= 4) { CGEventRef e=CGEventCreateScrollWheelEvent(NULL,kCGScrollEventUnitPixel,2,(int32_t)atof(argv[3]),(int32_t)atof(argv[2])); if(e){CGEventPost(kCGHIDEventTap,e);CFRelease(e);} }
  else if (!strcmp(argv[1],"key") && argc >= 3) {
    CGKeyCode code=special_code(argv[2]); CGEventRef down=CGEventCreateKeyboardEvent(NULL,code==UINT16_MAX?0:code,true); CGEventRef up=CGEventCreateKeyboardEvent(NULL,code==UINT16_MAX?0:code,false);
    if (!down || !up) return 3;
    if (code==UINT16_MAX) { CFStringRef text=CFStringCreateWithCString(NULL,argv[2],kCFStringEncodingUTF8); if(!text)return 3; CFIndex n=CFStringGetLength(text); UniChar chars[64]; if(n>64)n=64; CFStringGetCharacters(text,CFRangeMake(0,n),chars); CGEventKeyboardSetUnicodeString(down,n,chars); CGEventKeyboardSetUnicodeString(up,n,chars); CFRelease(text); }
    CGEventPost(kCGHIDEventTap,down); CGEventPost(kCGHIDEventTap,up); CFRelease(down); CFRelease(up);
  } else return 2;
  return 0;
}
'''


def normalize_command(command: str) -> str:
    clean = " ".join(str(command or "").strip().lower().replace("_", " ").replace("-", " ").split())
    aliases = {
        "route scan": "scan",
        "site scan": "scan",
        "browser scan": "scan",
        "proof scan": "scan",
        "codee doctor": "doctor",
        "codee heartbeat": "heartbeat",
        "host status": "status",
    }
    return aliases.get(clean, clean)


def read_state(root: Path) -> dict[str, Any]:
    return read_json(state_path(root))


def write_state(root: Path, payload: dict[str, Any]) -> None:
    payload["updated_at"] = now()
    write_json(state_path(root), payload)


def default_state(root: Path, device_name: str) -> dict[str, Any]:
    return {
        "ok": True,
        "schema": "codee.remote-host.v2",
        "version": VERSION,
        "created_at": now(),
        "updated_at": now(),
        "workspace": str(root),
        "device_name": device_name,
        "device_id": device_id(root, device_name),
        "allowlisted_commands": sorted(ALLOWLIST),
        "blocked_actions": sorted(BLOCKED_ACTIONS),
        "screen_streaming": "browser_host_requires_visible_consent",
        "input_control": "owner_setup_required",
        "native_input_enabled": False,
        "session_state": "not_started",
        "emergency_stop": False,
        "visible_consent_required": True,
        "queue_path": ".codee/remote-host/command-queue.json",
        "state_path": ".codee/remote-host/host-state.json",
        "pairing_path": ".codee/remote-host/pairing.json",
        "session_path": ".codee/remote-host/session.json",
        "toolbox_path": ".codee/remote-host/toolbox.json",
    }


def command_install(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    device_name = str(args.device_name or (os.uname().nodename if hasattr(os, "uname") else "Codee Desktop")).strip()
    payload = default_state(root, device_name)
    if args.write:
        write_state(root, payload)
        write_json(queue_path(root), {"schema": "codee.remote-command-queue.v2", "commands": [], "processed": []})
        write_json(remote_dir(root) / "toolbox.json", {"schema": "codee.remote-host-toolbox.v1", "created_at": now(), "tools": TOOLBOX, "command_presets": COMMAND_PRESETS})
        append_event(root, "RemoteHostInstalled", {"device_id": payload["device_id"], "device_name": device_name})
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print("Codee Remote Host")
        print(f"version={VERSION}")
        print(f"device_id={payload['device_id']}")
        print(f"screen_streaming={payload['screen_streaming']}")
        if args.write:
            print(f"state={root / '.codee' / 'remote-host' / 'host-state.json'}")
    return 0


def command_status(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    state = read_state(root)
    queue = read_json(queue_path(root))
    pairing = read_json(pairing_path(root))
    session = read_json(session_path(root))
    commands = queue.get("commands") if isinstance(queue.get("commands"), list) else []
    payload = {
        "ok": bool(state),
        "schema": "codee.remote-host-status.v1",
        "created_at": now(),
        "host_version": VERSION,
        "state_exists": bool(state),
        "device_id": state.get("device_id", ""),
        "device_name": state.get("device_name", ""),
        "session_state": state.get("session_state", "not_installed"),
        "emergency_stop": bool(state.get("emergency_stop")),
        "pending_commands": len(commands),
        "allowlisted_commands": sorted(ALLOWLIST),
        "screen_streaming": state.get("screen_streaming", "not_installed"),
        "input_control": state.get("input_control", "not_installed"),
        "background_service": str(Path.home() / "Library" / "LaunchAgents" / "ai.aik9.codee.remote.plist"),
        "pairing_expires_at": pairing.get("expires_at", ""),
        "session_id": session.get("session_id", ""),
    }
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print(f"Codee Remote Host status: ok={payload['ok']}")
        print(f"device_id={payload['device_id']}")
        print(f"session_state={payload['session_state']}")
        print(f"emergency_stop={payload['emergency_stop']}")
        print(f"pending_commands={payload['pending_commands']}")
        print(f"screen_streaming={payload['screen_streaming']}")
    return 0 if payload["ok"] else 1


def command_run_once(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    path = queue_path(root)
    queue = read_json(path)
    commands = queue.get("commands") if isinstance(queue.get("commands"), list) else []
    processed: list[dict[str, Any]] = []
    remaining: list[dict[str, Any]] = []
    for item in commands:
        command = normalize_command(str(item.get("command") if isinstance(item, dict) else item).strip())
        allowed = command in ALLOWLIST
        result = {
            "command": command,
            "allowed": allowed,
            "status": "accepted-dry-run" if allowed else "rejected",
            "preset": COMMAND_PRESETS.get(command, {}),
            "note": "Foundation host records queue results. Actual execution stays backend-gated and owner-visible.",
            "processed_at": now(),
        }
        processed.append(result)
        append_event(root, "RemoteHostCommandProcessed", result)
        if not allowed:
            remaining.append(item if isinstance(item, dict) else {"command": command})
    write_json(path, {"schema": "codee.remote-command-queue.v2", "commands": remaining, "processed": processed[-25:]})
    if args.json:
        print(json.dumps({"ok": True, "processed": processed, "remaining": remaining}, indent=2))
    else:
        print(f"Codee Remote Host run-once: processed={len(processed)} remaining={len(remaining)}")
    return 0


def command_pair(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    state = read_state(root)
    if not state:
        device_name = str(args.device_name or (os.uname().nodename if hasattr(os, "uname") else "Codee Desktop")).strip()
        state = default_state(root, device_name)
    ttl_minutes = max(1, min(60, int(str(args.expires_minutes or "10"))))
    code = "-".join([secrets.token_hex(2).upper(), secrets.token_hex(2).upper(), secrets.token_hex(1).upper()])
    expires_at = (dt.datetime.now(dt.timezone.utc) + dt.timedelta(minutes=ttl_minutes)).isoformat()
    payload = {
        "ok": True,
        "schema": "codee.remote-host-pairing.v1",
        "created_at": now(),
        "expires_at": expires_at,
        "ttl_minutes": ttl_minutes,
        "pairing_code": code,
        "device_id": state.get("device_id", ""),
        "device_name": state.get("device_name", ""),
        "workspace": str(root),
        "viewer_url": "https://clients.codee.chat/api/remote/viewer",
        "security_note": "This pair code does not stream the screen. It only proves owner-approved pairing intent.",
    }
    state.update({"session_state": "pairing_ready", "pairing_expires_at": expires_at, "last_pairing_code_hint": code[-4:], "emergency_stop": False})
    if args.write:
        write_state(root, state)
        write_json(pairing_path(root), payload)
        append_event(root, "RemoteHostPairingCreated", {"device_id": payload["device_id"], "expires_at": expires_at})
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print("Codee Remote Host pair code")
        print(f"pairing_code={code}")
        print(f"expires_at={expires_at}")
        if args.write:
            print(f"pairing={pairing_path(root)}")
    return 0


def command_session(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    state = read_state(root)
    if not state:
        print("Codee Remote Host is not installed. Run `python3 codee-remote-host.py install . --write` first.")
        return 1
    current = read_json(session_path(root))
    action = str(args.session_action or "status").strip().lower()
    session_id = str(current.get("session_id") or ("crs_" + secrets.token_hex(8)))
    if action == "start":
        status = "waiting_for_visible_desktop_consent"
        state.update({"session_state": status, "emergency_stop": False})
    elif action == "stop":
        status = "stopped_by_owner"
        state.update({"session_state": status, "emergency_stop": True})
    else:
        status = str(state.get("session_state") or current.get("status") or "not_started")
    payload = {
        "ok": True,
        "schema": "codee.remote-host-session.v1",
        "created_at": current.get("created_at") or now(),
        "updated_at": now(),
        "session_id": session_id,
        "action": action,
        "status": status,
        "device_id": state.get("device_id", ""),
        "visible_consent_required": True,
        "screen_streaming": "browser_host_requires_visible_consent",
        "input_control": state.get("input_control", "owner_setup_required"),
        "emergency_stop": bool(state.get("emergency_stop")),
    }
    if args.write or action in {"start", "stop"}:
        write_state(root, state)
        write_json(session_path(root), payload)
        append_event(root, "RemoteHostSessionUpdated", {"session_id": session_id, "action": action, "status": status})
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print("Codee Remote Host session")
        print(f"session_id={session_id}")
        print(f"status={status}")
        print(f"emergency_stop={payload['emergency_stop']}")
    return 0


def command_stop(args: argparse.Namespace) -> int:
    args.session_action = "stop"
    return command_session(args)


def command_enqueue(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    command = normalize_command(args.remote_command)
    allowed = command in ALLOWLIST
    item = {
        "id": "rcmd_" + secrets.token_hex(6),
        "created_at": now(),
        "command": command,
        "allowed": allowed,
        "preset": COMMAND_PRESETS.get(command, {}),
        "source": "owner-remote-viewer",
        "status": "queued" if allowed else "rejected",
    }
    path = queue_path(root)
    queue = read_json(path)
    commands = queue.get("commands") if isinstance(queue.get("commands"), list) else []
    if allowed:
        commands.append(item)
    payload = {"ok": allowed, "schema": "codee.remote-command-enqueue.v1", "queued": item if allowed else None, "rejected": None if allowed else item, "allowlisted_commands": sorted(ALLOWLIST)}
    if args.write:
        write_json(path, {"schema": "codee.remote-command-queue.v2", "commands": commands, "processed": queue.get("processed", []) if isinstance(queue.get("processed"), list) else []})
        append_event(root, "RemoteHostCommandQueued" if allowed else "RemoteHostCommandRejected", item)
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print(f"Codee Remote Host enqueue: ok={allowed} command={command}")
        if not allowed:
            print(f"allowed={', '.join(sorted(ALLOWLIST))}")
    return 0 if allowed else 2


def command_toolbox(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    payload = {"ok": True, "schema": "codee.remote-host-toolbox.v1", "created_at": now(), "tools": TOOLBOX, "command_presets": COMMAND_PRESETS, "blocked_actions": sorted(BLOCKED_ACTIONS)}
    if args.write:
        write_json(remote_dir(root) / "toolbox.json", payload)
        append_event(root, "RemoteHostToolboxWritten", {"tool_count": len(TOOLBOX)})
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print(f"Codee Remote Host toolbox: tools={len(TOOLBOX)}")
        if args.write:
            print(f"toolbox={remote_dir(root) / 'toolbox.json'}")
    return 0


def command_proof(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    events: list[dict[str, Any]] = []
    event_file = remote_dir(root) / "events.jsonl"
    if event_file.exists():
        for line in event_file.read_text(encoding="utf-8", errors="replace").splitlines()[-100:]:
            try:
                events.append(json.loads(line))
            except Exception:
                continue
    payload = {
        "ok": True,
        "schema": "codee.remote-host-proof.v1",
        "created_at": now(),
        "host_version": VERSION,
        "workspace": str(root),
        "state": read_state(root),
        "pairing": read_json(pairing_path(root)),
        "session": read_json(session_path(root)),
        "queue": read_json(queue_path(root)),
        "event_count": len(events),
        "latest_events": events[-25:],
        "public_safety": {
            "browser_screen_streaming_live": True,
            "native_host_screen_streaming_live": False,
            "input_control_live": _native_input_enabled(root),
            "reason": "Browser capture still requires visible screen consent. The native mouse and keyboard helper is available only after explicit owner setup and macOS Accessibility approval.",
        },
    }
    if args.write:
        write_json(proof_path(root), payload)
        append_event(root, "RemoteHostProofExported", {"proof": str(proof_path(root))})
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print("Codee Remote Host proof")
        print(f"events={len(events)}")
        if args.write:
            print(f"proof={proof_path(root)}")
    return 0


def command_audit(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    event_path = root / ".codee" / "remote-host" / "events.jsonl"
    events = []
    if event_path.exists():
        for line in event_path.read_text(encoding="utf-8", errors="replace").splitlines()[-100:]:
            try:
                events.append(json.loads(line))
            except Exception:
                continue
    payload = {"ok": True, "schema": "codee.remote-host-audit.v1", "created_at": now(), "event_count": len(events), "latest_events": events[-10:]}
    write_json(root / ".codee" / "remote-host" / "latest-audit.json", payload)
    if args.json:
        print(json.dumps(payload, indent=2))
    else:
        print(f"Codee Remote Host audit: events={len(events)}")
        print(f"report={root / '.codee' / 'remote-host' / 'latest-audit.json'}")
    return 0


def command_native_setup(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    if sys.platform != "darwin":
        print("Native mouse and keyboard setup is currently available only on macOS.")
        return 2
    state = read_state(root)
    if not state:
        print("Install the Codee Remote host first.")
        return 1
    clang = str(subprocess.run(["/usr/bin/xcrun", "--find", "clang"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, check=False).stdout or "").strip()
    if not clang:
        print("Apple Command Line Tools are required for the native input helper. Run `xcode-select --install` and retry.")
        return 2
    sdk = str(subprocess.run(["/usr/bin/xcrun", "--show-sdk-path"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, check=False).stdout or "").strip()
    source = remote_dir(root) / "codee-remote-input.c"
    helper = _native_helper_path(root)
    source.write_text(NATIVE_INPUT_SOURCE, encoding="utf-8")
    compile_argv = [clang]
    if sdk:
        compile_argv.extend(["-isysroot", sdk])
    compile_argv.extend([str(source), "-framework", "ApplicationServices", "-framework", "CoreFoundation", "-o", str(helper)])
    completed = subprocess.run(compile_argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False)
    if completed.returncode != 0:
        print(str(completed.stdout or "")[-4000:])
        return 1
    helper.chmod(0o700)
    state["native_input_enabled"] = bool(args.enable)
    state["input_control"] = "enabled-owner-approved" if args.enable else "installed-locked"
    write_state(root, state)
    append_event(root, "RemoteNativeInputConfigured", {"enabled": bool(args.enable), "helper": str(helper)})
    print(f"Codee Remote native input helper: installed=True enabled={bool(args.enable)}")
    print("macOS must allow this helper under System Settings > Privacy & Security > Accessibility.")
    return 0


def command_service_install(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    if sys.platform != "darwin":
        print("The background host service installer is currently available only on macOS.")
        return 2
    label = "ai.aik9.codee.remote"
    agent_dir = Path.home() / "Library" / "LaunchAgents"
    plist_path = agent_dir / f"{label}.plist"
    agent_dir.mkdir(parents=True, exist_ok=True)
    log_dir = remote_dir(root)
    log_dir.mkdir(parents=True, exist_ok=True)
    payload = {
        "Label": label,
        "ProgramArguments": [sys.executable, str(Path(__file__).resolve()), "cloud-daemon", str(root)],
        "RunAtLoad": True,
        "KeepAlive": True,
        "ThrottleInterval": 15,
        "StandardOutPath": str(log_dir / "service.stdout.log"),
        "StandardErrorPath": str(log_dir / "service.stderr.log"),
        "ProcessType": "Interactive",
    }
    with plist_path.open("wb") as handle:
        plistlib.dump(payload, handle)
    subprocess.run(["/bin/launchctl", "bootout", f"gui/{os.getuid()}", str(plist_path)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
    loaded = subprocess.run(["/bin/launchctl", "bootstrap", f"gui/{os.getuid()}", str(plist_path)], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False)
    append_event(root, "RemoteBackgroundServiceInstalled", {"plist": str(plist_path), "loaded": loaded.returncode == 0})
    print(f"Codee Remote background service: installed=True loaded={loaded.returncode == 0}")
    print(f"service={plist_path}")
    if loaded.returncode != 0:
        print(str(loaded.stdout or "")[-2000:])
    return 0 if loaded.returncode == 0 else 1


def command_cloud_start(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    state = read_state(root)
    if not state:
        print("Codee Remote Host is not installed. Run `python3 codee-remote-host.py install . --write` first.")
        return 1
    owner_token = str(os.getenv("CODEE_REMOTE_OWNER_TOKEN") or os.getenv("ADMIN_TOKEN") or "").strip()
    if not owner_token and sys.platform == "darwin":
        try:
            keychain = subprocess.run(
                ["security", "find-generic-password", "-s", "AIK9-Codee-Remote", "-w"],
                stdout=subprocess.PIPE,
                stderr=subprocess.DEVNULL,
                text=True,
                timeout=10,
                check=False,
            )
            owner_token = str(keychain.stdout or "").strip() if keychain.returncode == 0 else ""
        except Exception:
            owner_token = ""
    if not owner_token:
        print("Missing CODEE_REMOTE_OWNER_TOKEN or the AIK9-Codee-Remote macOS Keychain entry. The owner token stays local and is never written to the session file.")
        return 2
    status, payload = api_json(
        "POST",
        f"{REMOTE_API_BASE}/sessions",
        token=owner_token,
        payload={
            "device_name": str(args.device_name or state.get("device_name") or "Codee Desktop").strip(),
            "device_id": str(state.get("device_id") or ""),
            "ttl_minutes": int(args.ttl_minutes or 120),
        },
    )
    if status != 201 or not payload.get("ok"):
        print(json.dumps({"ok": False, "status": status, "error": payload.get("error") or "session_create_failed"}, indent=2))
        return 1
    session = {
        "schema": "codee.remote-cloud-host.v1",
        "created_at": now(),
        "api_base": REMOTE_API_BASE,
        "room_id": payload["room_id"],
        "device_id": payload.get("device_id") or state.get("device_id", ""),
        "host_token": payload["host_token"],
        "host_url": payload["host_url"],
        "viewer_url": payload["viewer_url"],
        "pair_code": payload["pair_code"],
        "expires_at": payload["expires_at"],
        "last_sequence": 0,
    }
    write_json(cloud_session_path(root), session)
    try:
        os.chmod(cloud_session_path(root), 0o600)
    except Exception:
        pass
    append_event(root, "RemoteCloudSessionCreated", {"room_id": payload["room_id"], "expires_at": payload["expires_at"]})
    public = {key: value for key, value in session.items() if key not in {"host_token"}}
    public["pair_code"] = payload["pair_code"]
    if args.json:
        print(json.dumps(public, indent=2))
    else:
        print("Codee Remote cloud session ready")
        print(f"pair_code={payload['pair_code']}")
        print(f"viewer_url={payload['viewer_url']}")
        print(f"host_url={payload['host_url']}")
        print(f"expires_at={payload['expires_at']}")
        print("Run `python3 codee-remote-host.py cloud-run .` in a second terminal to accept allowlisted Codee commands.")
    return 0


def command_cloud_run(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    session = _cloud_session(root)
    room_id = str(session.get("room_id") or "")
    host_token = str(session.get("host_token") or "")
    api_base = str(session.get("api_base") or REMOTE_API_BASE).rstrip("/")
    if not room_id or not host_token:
        print("No cloud session found. Run `python3 codee-remote-host.py cloud-start .` first.")
        return 1
    after = int(session.get("last_sequence") or 0)
    last_heartbeat = 0.0
    native_input = _native_input_enabled(root)
    api_json(
        "POST",
        f"{api_base}/sessions/{urllib.parse.quote(room_id, safe='')}/signals",
        token=host_token,
        payload={"kind": "presence", "payload": {"native_input": native_input, "host_version": VERSION}},
    )
    print(f"Codee Remote command bridge active for {room_id}. Ctrl-C stops the local bridge; viewer Emergency Stop revokes the session.")
    while True:
        if time.monotonic() - last_heartbeat >= 300:
            heartbeat_status, heartbeat = api_json(
                "POST",
                f"{api_base}/sessions/{urllib.parse.quote(room_id, safe='')}/heartbeat",
                token=host_token,
                payload={},
            )
            if heartbeat_status == 200:
                session["expires_at"] = heartbeat.get("expires_at", session.get("expires_at", ""))
                last_heartbeat = time.monotonic()
        url = f"{api_base}/sessions/{urllib.parse.quote(room_id, safe='')}/signals?after={after}"
        status, payload = api_json("GET", url, token=host_token)
        if status in {410, 404}:
            print(f"Remote session closed: {payload.get('error') or status}")
            return 0
        if status != 200:
            print(f"Remote bridge poll failed: status={status} error={payload.get('error') or 'unknown'}")
            if args.once:
                return 1
            time.sleep(max(1.0, float(args.poll_seconds or 2)))
            continue
        for signal in payload.get("signals") or []:
            if not isinstance(signal, dict):
                continue
            after = max(after, int(signal.get("seq") or 0))
            if signal.get("kind") == "input":
                request_payload = signal.get("payload") if isinstance(signal.get("payload"), dict) else {}
                result = _execute_native_input(root, request_payload)
                append_event(root, "RemoteNativeInput", {"action": result.get("action"), "status": result.get("status"), "ok": result.get("ok")})
                continue
            if signal.get("kind") != "command":
                continue
            request_payload = signal.get("payload") if isinstance(signal.get("payload"), dict) else {}
            result = _execute_cloud_command(root, str(request_payload.get("command") or ""))
            result["request_id"] = str(request_payload.get("request_id") or "")
            api_json(
                "POST",
                f"{api_base}/sessions/{urllib.parse.quote(room_id, safe='')}/signals",
                token=host_token,
                payload={"kind": "command-result", "payload": result},
            )
            append_event(root, "RemoteCloudCommandProcessed", {"command": result.get("command"), "status": result.get("status"), "ok": result.get("ok")})
            print(f"command={result.get('command')} status={result.get('status')} ok={result.get('ok')}")
        session["last_sequence"] = after
        write_json(cloud_session_path(root), session)
        try:
            os.chmod(cloud_session_path(root), 0o600)
        except Exception:
            pass
        if args.once:
            return 0
        time.sleep(max(1.0, float(args.poll_seconds or 2)))


def command_cloud_daemon(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    print(f"Codee Remote background host active for {root}")
    while True:
        session = _cloud_session(root)
        room_id = str(session.get("room_id") or "")
        host_token = str(session.get("host_token") or "")
        valid = False
        if room_id and host_token:
            status, payload = api_json("GET", f"{REMOTE_API_BASE}/sessions/{urllib.parse.quote(room_id, safe='')}", token=host_token)
            valid = status == 200 and bool(payload.get("ok"))
        if not valid:
            start_args = argparse.Namespace(path=str(root), device_name="", ttl_minutes="120", json=False)
            if command_cloud_start(start_args) != 0:
                time.sleep(30)
                continue
        run_args = argparse.Namespace(path=str(root), poll_seconds="2", once=False)
        command_cloud_run(run_args)
        time.sleep(5)


def command_cloud_stop(args: argparse.Namespace) -> int:
    root = Path(args.path).expanduser().resolve()
    session = _cloud_session(root)
    room_id = str(session.get("room_id") or "")
    host_token = str(session.get("host_token") or "")
    api_base = str(session.get("api_base") or REMOTE_API_BASE).rstrip("/")
    if not room_id or not host_token:
        print("No active cloud session found.")
        return 1
    status, payload = api_json("POST", f"{api_base}/sessions/{urllib.parse.quote(room_id, safe='')}/stop", token=host_token, payload={})
    print(json.dumps({"ok": bool(payload.get("ok")), "status": status, "room_id": room_id}, indent=2))
    return 0 if status == 200 else 1


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description="Codee Remote Host foundation. No silent screen streaming or public owner credentials.")
    parser.add_argument("--version", action="version", version=VERSION)
    sub = parser.add_subparsers(dest="command", required=True)
    install = sub.add_parser("install", help="Install local host state and queue files.")
    install.add_argument("path", nargs="?", default=".")
    install.add_argument("--device-name", default="")
    install.add_argument("--write", action="store_true")
    install.add_argument("--json", action="store_true")
    install.set_defaults(func=command_install)
    pair = sub.add_parser("pair", help="Create an expiring owner pairing code.")
    pair.add_argument("path", nargs="?", default=".")
    pair.add_argument("--device-name", default="")
    pair.add_argument("--expires-minutes", default="10")
    pair.add_argument("--write", action="store_true")
    pair.add_argument("--json", action="store_true")
    pair.set_defaults(func=command_pair)
    session = sub.add_parser("session", help="Start, stop, or inspect a visible remote session packet.")
    session.add_argument("path", nargs="?", default=".")
    session.add_argument("--session-action", default="status", choices=["start", "stop", "status"])
    session.add_argument("--write", action="store_true")
    session.add_argument("--json", action="store_true")
    session.set_defaults(func=command_session)
    stop = sub.add_parser("stop", help="Trigger the owner emergency stop state.")
    stop.add_argument("path", nargs="?", default=".")
    stop.add_argument("--write", action="store_true")
    stop.add_argument("--json", action="store_true")
    stop.set_defaults(func=command_stop)
    enqueue = sub.add_parser("enqueue", help="Queue one allowlisted Codee command for the owner-visible bridge.")
    enqueue.add_argument("path", nargs="?", default=".")
    enqueue.add_argument("--command", dest="remote_command", required=True)
    enqueue.add_argument("--write", action="store_true")
    enqueue.add_argument("--json", action="store_true")
    enqueue.set_defaults(func=command_enqueue)
    toolbox = sub.add_parser("toolbox", help="Write the local owner toolbox manifest.")
    toolbox.add_argument("path", nargs="?", default=".")
    toolbox.add_argument("--write", action="store_true")
    toolbox.add_argument("--json", action="store_true")
    toolbox.set_defaults(func=command_toolbox)
    status = sub.add_parser("status", help="Show local host status.")
    status.add_argument("path", nargs="?", default=".")
    status.add_argument("--json", action="store_true")
    status.set_defaults(func=command_status)
    run_once = sub.add_parser("run-once", help="Process one local command queue pass in dry-run mode.")
    run_once.add_argument("path", nargs="?", default=".")
    run_once.add_argument("--json", action="store_true")
    run_once.set_defaults(func=command_run_once)
    proof = sub.add_parser("proof", help="Export host pairing, session, queue, and audit proof.")
    proof.add_argument("path", nargs="?", default=".")
    proof.add_argument("--write", action="store_true")
    proof.add_argument("--json", action="store_true")
    proof.set_defaults(func=command_proof)
    audit = sub.add_parser("audit", help="Summarize host events.")
    audit.add_argument("path", nargs="?", default=".")
    audit.add_argument("--json", action="store_true")
    audit.set_defaults(func=command_audit)
    native_setup = sub.add_parser("native-setup", help="Build and explicitly enable the macOS mouse and keyboard helper.")
    native_setup.add_argument("path", nargs="?", default=".")
    native_setup.add_argument("--enable", action="store_true", help="Owner approval to accept native input after visible screen consent.")
    native_setup.set_defaults(func=command_native_setup)
    service_install = sub.add_parser("service-install", help="Install and load the per-user macOS background host service.")
    service_install.add_argument("path", nargs="?", default=".")
    service_install.set_defaults(func=command_service_install)
    cloud_start = sub.add_parser("cloud-start", help="Create a short-lived authenticated Codee Remote cloud session.")
    cloud_start.add_argument("path", nargs="?", default=".")
    cloud_start.add_argument("--device-name", default="")
    cloud_start.add_argument("--ttl-minutes", default="120")
    cloud_start.add_argument("--json", action="store_true")
    cloud_start.set_defaults(func=command_cloud_start)
    cloud_run = sub.add_parser("cloud-run", help="Poll and execute the strictly allowlisted Codee command bridge.")
    cloud_run.add_argument("path", nargs="?", default=".")
    cloud_run.add_argument("--poll-seconds", default="2")
    cloud_run.add_argument("--once", action="store_true")
    cloud_run.set_defaults(func=command_cloud_run)
    cloud_daemon = sub.add_parser("cloud-daemon", help="Keep the registered desktop online and renew its secure room.")
    cloud_daemon.add_argument("path", nargs="?", default=".")
    cloud_daemon.set_defaults(func=command_cloud_daemon)
    cloud_stop = sub.add_parser("cloud-stop", help="Revoke the active Codee Remote cloud session.")
    cloud_stop.add_argument("path", nargs="?", default=".")
    cloud_stop.set_defaults(func=command_cloud_stop)
    return parser


def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)
    return int(args.func(args))


if __name__ == "__main__":
    raise SystemExit(main())
