#!/usr/bin/env bash
# aironclaw — minimal CLI wrapper over the AIronClaw REST API.
#
# Reads:
#   AIRONCLAW_TOKEN     personal access token (required)
#   AIRONCLAW_BASE_URL  default: https://dashboard.aironclaw.com
#
# Generic usage:
#   aironclaw <method> <path> [body-json]
#     aironclaw GET /api/mcp
#     aironclaw POST /api/mcp '{"name":"x","url":"https://..."}'
#     aironclaw PATCH /api/llm/<id> '{"defaultModel":"gpt-4o-mini"}'
#     aironclaw DELETE /api/keys/<id>
#
# Convenience subcommands (curated; the generic form covers everything else):
#   aironclaw mcp list
#   aironclaw mcp get <id>
#   aironclaw mcp delete <id>
#   aironclaw mcp tools <id>
#   aironclaw mcp rules <id>
#   aironclaw llm list
#   aironclaw llm get <id>
#   aironclaw llm delete <id>
#   aironclaw llm rules <id>
#   aironclaw keys list
#   aironclaw keys delete <id>
#   aironclaw logs [--limit 50] [--type <event_type>]
#   aironclaw whoami

set -euo pipefail

BASE="${AIRONCLAW_BASE_URL:-https://dashboard.aironclaw.com}"
TOKEN="${AIRONCLAW_TOKEN:-}"

die() { printf 'aironclaw: %s\n' "$*" >&2; exit 1; }

if [[ -z "$TOKEN" ]]; then
  cat >&2 <<'EOF'
aironclaw: AIRONCLAW_TOKEN is not set.

To get one:
  1. Open https://dashboard.aironclaw.com/dashboard/profile
  2. Sign in (and complete 2FA if enabled).
  3. Scroll to "REST API Access" → click "Generate token".
  4. Copy the token shown in the amber banner — it is displayed exactly once.
  5. Export it (and optionally the base URL):

       export AIRONCLAW_TOKEN="<paste-here>"
       export AIRONCLAW_BASE_URL="https://dashboard.aironclaw.com"

Then re-run this command.
EOF
  exit 2
fi

command -v jq >/dev/null 2>&1 || die "jq is required but not installed"
command -v curl >/dev/null 2>&1 || die "curl is required but not installed"

# Low-level request: aironclaw_call <METHOD> <PATH> [body-json]
aironclaw_call() {
  local method="$1" path="$2" body="${3:-}"
  local url="${BASE}${path}"
  local args=(-fsS -X "$method" -H "Authorization: Bearer ${TOKEN}")
  if [[ -n "$body" ]]; then
    args+=(-H 'Content-Type: application/json' -d "$body")
  fi
  # -f makes curl exit non-zero on >=400 but suppresses the body. Re-fetch
  # explicitly on failure so the user sees the error message.
  if ! curl "${args[@]}" "$url" 2>/dev/null; then
    local code
    code=$(curl -sS -o /tmp/aironclaw.err -w '%{http_code}' \
            -X "$method" -H "Authorization: Bearer ${TOKEN}" \
            ${body:+-H 'Content-Type: application/json' -d "$body"} \
            "$url")
    printf '%s %s -> HTTP %s\n%s\n' "$method" "$path" "$code" \
      "$(cat /tmp/aironclaw.err 2>/dev/null || true)" >&2
    return 1
  fi
}

cmd_mcp() {
  local sub="${1:-list}"; shift || true
  case "$sub" in
    list)   aironclaw_call GET "/api/mcp" | jq ;;
    get)    [[ $# -ge 1 ]] || die "mcp get <id>"; aironclaw_call GET "/api/mcp/$1" | jq ;;
    delete) [[ $# -ge 1 ]] || die "mcp delete <id>"; aironclaw_call DELETE "/api/mcp/$1" | jq ;;
    tools)  [[ $# -ge 1 ]] || die "mcp tools <id>"; aironclaw_call POST "/api/mcp/$1/tools" | jq ;;
    rules)  [[ $# -ge 1 ]] || die "mcp rules <id>"; aironclaw_call GET "/api/mcp/$1/rules" | jq ;;
    *) die "unknown mcp subcommand: $sub" ;;
  esac
}

cmd_llm() {
  local sub="${1:-list}"; shift || true
  case "$sub" in
    list)   aironclaw_call GET "/api/llm" | jq ;;
    get)    [[ $# -ge 1 ]] || die "llm get <id>"; aironclaw_call GET "/api/llm/$1" | jq ;;
    delete) [[ $# -ge 1 ]] || die "llm delete <id>"; aironclaw_call DELETE "/api/llm/$1" | jq ;;
    rules)  [[ $# -ge 1 ]] || die "llm rules <id>"; aironclaw_call GET "/api/llm/$1/rules" | jq ;;
    *) die "unknown llm subcommand: $sub" ;;
  esac
}

cmd_keys() {
  local sub="${1:-list}"; shift || true
  case "$sub" in
    list)   aironclaw_call GET "/api/keys" | jq ;;
    delete) [[ $# -ge 1 ]] || die "keys delete <id>"; aironclaw_call DELETE "/api/keys/$1" | jq ;;
    *) die "unknown keys subcommand: $sub" ;;
  esac
}

cmd_logs() {
  local limit=50 type=""
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --limit) limit="$2"; shift 2 ;;
      --type)  type="$2";  shift 2 ;;
      *) die "unknown logs flag: $1" ;;
    esac
  done
  local q="limit=${limit}"
  [[ -n "$type" ]] && q="${q}&event_type=${type}"
  aironclaw_call GET "/api/logs?${q}" | jq
}

cmd_whoami() {
  aironclaw_call GET "/api/profile" | jq
}

main() {
  if [[ $# -eq 0 ]]; then
    sed -n '3,28p' "$0" | sed 's/^# \{0,1\}//'
    exit 0
  fi

  local first="$1"; shift
  case "$first" in
    GET|POST|PUT|PATCH|DELETE)
      [[ $# -ge 1 ]] || die "missing path after $first"
      local path="$1"; shift
      local body="${1:-}"
      aironclaw_call "$first" "$path" "$body" | jq
      ;;
    mcp)    cmd_mcp    "$@" ;;
    llm)    cmd_llm    "$@" ;;
    keys)   cmd_keys   "$@" ;;
    logs)   cmd_logs   "$@" ;;
    whoami) cmd_whoami       ;;
    -h|--help|help) sed -n '3,28p' "$0" | sed 's/^# \{0,1\}//' ;;
    *) die "unknown command: $first (use --help)" ;;
  esac
}

main "$@"
