#!/usr/bin/env bash
set -euo pipefail

CODEX_HOME_DIR="${CODEX_HOME:-$HOME/.codex}"
CONFIG_PATH="${CODEX_CONFIG_PATH:-$CODEX_HOME_DIR/config.toml}"
API_BASE="${API_BASE:-http://127.0.0.1:8000}"
DRY_RUN=0
SKIP_VERIFY=0
MCP_MODE="remove"
MCP_NAME="${STATE_HUB_MCP_NAME:-dev-hub}"
MCP_COMMAND="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/codex-state-hub-mcp.sh"

usage() {
  cat <<'USAGE'
Usage: scripts/configure-codex.sh [options]

Enable direct network access for Codex workspace-write sandboxes and verify
that the sandbox can reach the local State Hub.

Options:
  --codex-home DIR  Codex home containing config.toml. Default: $CODEX_HOME or ~/.codex.
  --api-base URL    State Hub API base. Default: http://127.0.0.1:8000.
  --dry-run         Show the configuration change without writing it.
  --skip-verify     Do not run the sandboxed State Hub health check.
  --with-mcp        Opt in to the experimental slim State Hub MCP server.
  --skip-mcp        Do not add or remove a State Hub MCP registration.
  -h, --help        Show this help.
USAGE
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --codex-home)
      test -n "${2:-}" || { echo "ERROR: --codex-home requires a directory" >&2; exit 2; }
      CODEX_HOME_DIR="$2"
      CONFIG_PATH="$CODEX_HOME_DIR/config.toml"
      shift 2
      ;;
    --api-base)
      test -n "${2:-}" || { echo "ERROR: --api-base requires a URL" >&2; exit 2; }
      API_BASE="$2"
      shift 2
      ;;
    --dry-run) DRY_RUN=1; shift ;;
    --skip-verify) SKIP_VERIFY=1; shift ;;
    --with-mcp) MCP_MODE="add"; shift ;;
    --skip-mcp) MCP_MODE="skip"; shift ;;
    -h|--help) usage; exit 0 ;;
    *) echo "ERROR: unknown argument: $1" >&2; usage >&2; exit 2 ;;
  esac
done

python3 - "$CONFIG_PATH" "$DRY_RUN" <<'PY'
import re
import sys
import tomllib
from pathlib import Path

path = Path(sys.argv[1])
dry_run = sys.argv[2] == "1"
original = path.read_text(encoding="utf-8") if path.exists() else ""
if original:
    tomllib.loads(original)

header = "[sandbox_workspace_write]"
lines = original.splitlines()
start = next((i for i, line in enumerate(lines) if line.strip() == header), None)

if start is None:
    if lines and lines[-1].strip():
        lines.append("")
    lines.extend([header, "network_access = true"])
else:
    end = next(
        (i for i in range(start + 1, len(lines)) if re.match(r"^\s*\[", lines[i])),
        len(lines),
    )
    setting = next(
        (i for i in range(start + 1, end) if re.match(r"^\s*network_access\s*=", lines[i])),
        None,
    )
    if setting is None:
        lines.insert(end, "network_access = true")
    else:
        lines[setting] = "network_access = true"

updated = "\n".join(lines).rstrip() + "\n"
tomllib.loads(updated)

if updated == original:
    print(f"OK: {path} already enables sandbox workspace-write network access")
elif dry_run:
    print(f"DRY-RUN: would enable sandbox_workspace_write.network_access in {path}")
else:
    path.parent.mkdir(parents=True, exist_ok=True)
    temporary = path.with_suffix(path.suffix + ".tmp")
    temporary.write_text(updated, encoding="utf-8")
    temporary.chmod(0o600)
    temporary.replace(path)
    print(f"OK: enabled sandbox_workspace_write.network_access in {path}")
PY

if [ "$MCP_MODE" = "add" ]; then
  if [ "$DRY_RUN" -eq 1 ]; then
    echo "DRY-RUN: would register Codex MCP server $MCP_NAME -> $MCP_COMMAND"
  elif ! command -v codex >/dev/null 2>&1; then
    echo "WARN: codex is not on PATH; State Hub MCP registration was skipped." >&2
  elif CODEX_HOME="$CODEX_HOME_DIR" codex mcp get "$MCP_NAME" >/dev/null 2>&1; then
    echo "OK: Codex MCP server $MCP_NAME is already registered"
  else
    CODEX_HOME="$CODEX_HOME_DIR" codex mcp add "$MCP_NAME" -- "$MCP_COMMAND"
    echo "OK: registered Codex MCP server $MCP_NAME -> $MCP_COMMAND"
  fi
elif [ "$MCP_MODE" = "remove" ]; then
  if [ "$DRY_RUN" -eq 1 ]; then
    echo "DRY-RUN: would remove Codex MCP server $MCP_NAME if registered"
  elif command -v codex >/dev/null 2>&1 \
      && CODEX_HOME="$CODEX_HOME_DIR" codex mcp get "$MCP_NAME" >/dev/null 2>&1; then
    CODEX_HOME="$CODEX_HOME_DIR" codex mcp remove "$MCP_NAME"
    echo "OK: removed Codex MCP server $MCP_NAME; use REST/statehub CLI by default"
  else
    echo "OK: Codex MCP server $MCP_NAME is not registered"
  fi
fi

if [ "$DRY_RUN" -eq 1 ] || [ "$SKIP_VERIFY" -eq 1 ]; then
  exit 0
fi

if ! command -v codex >/dev/null 2>&1; then
  echo "WARN: codex is not on PATH; configuration was written but not verified." >&2
  exit 0
fi

HEALTH_URL="${API_BASE%/}/state/health"
if timeout 10 codex sandbox -- curl -fsS --max-time 3 "$HEALTH_URL" >/dev/null 2>&1; then
  echo "OK: Codex sandbox can reach State Hub at $HEALTH_URL"
else
  echo "WARN: Codex sandbox still cannot reach $HEALTH_URL." >&2
  echo "WARN: A managed permission profile may enforce restricted networking/--unshare-net." >&2
  echo "WARN: Retry State Hub REST/CLI commands with escalated execution or change the managed profile." >&2
fi
