#!/usr/bin/env bash
# boots.sh installer: checks a Boots checkout and registers the Boots Studio MCP server with Claude Code.
#
#   ./install.sh <path-to-boots>                 print the steps for that checkout (changes nothing)
#   ./install.sh <path-to-boots> --register      also run `claude mcp add boots-studio ...` (skipped if already registered)
#   ./install.sh <path-to-boots> --register --key-ref 'op://<vault>/<item>/<field>'
#                                                register with a 1Password reference (never the key itself)
#   ./install.sh <path-to-boots> --install       also run `./run exec foundations.install` in the checkout
#
# Safe to run more than once. It never downloads anything, never reads or stores a secret, and only writes
# through `claude mcp add` (user scope by default; pass --scope local|project|user to change it).
set -euo pipefail

usage() { sed -n '2,11p' "$0" | sed 's/^# \{0,1\}//'; }

BOOTS_DIR="${BOOTS_DIR:-}"
REGISTER=0
INSTALL=0
KEY_REF=""
SCOPE="user"
NAME="boots-studio"

while [ $# -gt 0 ]; do
  case "$1" in
    -h|--help) usage; exit 0 ;;
    --register) REGISTER=1 ;;
    --install) INSTALL=1 ;;
    --key-ref) shift; KEY_REF="${1:-}" ;;
    --key-ref=*) KEY_REF="${1#*=}" ;;
    --scope) shift; SCOPE="${1:-}" ;;
    --scope=*) SCOPE="${1#*=}" ;;
    --name) shift; NAME="${1:-}" ;;
    -*) echo "install.sh: unknown option $1" >&2; usage >&2; exit 2 ;;
    *) BOOTS_DIR="$1" ;;
  esac
  shift
done

say()  { printf '  %s\n' "$*"; }
ok()   { printf '  \033[32m✓\033[0m %s\n' "$*"; }
warn() { printf '  \033[33m!\033[0m %s\n' "$*"; }
die()  { printf '  \033[31m✗\033[0m %s\n' "$*" >&2; exit 1; }

echo "boots.sh · Boots Studio setup"
echo

[ -n "$BOOTS_DIR" ] || { usage >&2; echo >&2; die "Give the path to a Boots checkout (git clone git@github.com:widgeit/boots.git)."; }
[ -d "$BOOTS_DIR" ] || die "No such directory: $BOOTS_DIR"
BOOTS_DIR="$(cd "$BOOTS_DIR" && pwd -P)"
TASK="$BOOTS_DIR/foundations/task.ts"
[ -f "$TASK" ] || die "$BOOTS_DIR does not look like a Boots checkout (missing foundations/task.ts)."
ok "Boots checkout: $BOOTS_DIR"

case "$SCOPE" in local|project|user) ;; *) die "--scope must be local, project or user" ;; esac
case "$NAME" in *[!A-Za-z0-9_-]*|"") die "--name may only use letters, digits, - and _" ;; esac
if [ -n "$KEY_REF" ]; then
  case "$KEY_REF" in
    op://*/*/*) ok "Key source: 1Password reference (the server runs \`op read\` when a tool first needs it)" ;;
    *) die "--key-ref must be a 1Password reference like op://vault/item/field. Never pass the key itself." ;;
  esac
fi

BUN="$(command -v bun || true)"
if [ -n "$BUN" ]; then ok "bun: $BUN"; else warn "bun not found. Install it: https://bun.sh (the MCP server runs on Bun)."; BUN="bun"; fi
OP="$(command -v op || true)"
if [ -n "$OP" ]; then ok "1Password CLI: $OP"; elif [ -n "$KEY_REF" ]; then warn "op not found; install the 1Password CLI so the server can read $KEY_REF"; fi
CLAUDE="$(command -v claude || true)"
if [ -n "$CLAUDE" ]; then ok "Claude Code: $CLAUDE"; else warn "claude not found; the steps below still work for other agents."; fi

# The command an agent runs to start the server. Full paths, because agents start servers with a minimal PATH.
ADD=(mcp add --scope "$SCOPE" "$NAME")
if [ -n "$KEY_REF" ]; then
  ADD+=(--env "BOOTS_PROVIDER_KEY=$KEY_REF")
  [ -n "$OP" ] && ADD+=(--env "BOOTS_OP_BIN=$OP")
fi
ADD+=(-- "$BUN" "$TASK" mcp)

echo
echo "Steps"
say "1. Install once:         (cd \"$BOOTS_DIR\" && ./run exec foundations.install)"
say "2. Start the studio:     (cd \"$BOOTS_DIR\" && ./run exec foundations.studio)   # http://127.0.0.1:4310/studio/"
printf '  3. Register the MCP:     claude'; printf ' %q' "${ADD[@]}"; echo
say "4. Ask your agent:       \"Use boots-studio to make a complete brand for a fraud-checking API for online shops.\""
echo
say "Other agents (Codex, Muse, Grok, OMP): use the studio's Connect an agent dialog, or point them at:"
say "  command: $BUN   args: $TASK mcp"

if [ "$INSTALL" = 1 ]; then
  echo
  echo "Installing"
  (cd "$BOOTS_DIR" && ./run exec foundations.install)
  ok "foundations.install finished"
fi

if [ "$REGISTER" = 1 ]; then
  echo
  echo "Registering"
  [ -n "$CLAUDE" ] || die "claude is not on PATH; install Claude Code or register by hand with the command in step 3."
  if "$CLAUDE" mcp get "$NAME" >/dev/null 2>&1; then
    ok "$NAME is already registered; leaving it as is (remove it with: claude mcp remove $NAME --scope $SCOPE)"
  else
    "$CLAUDE" "${ADD[@]}"
    ok "Registered $NAME ($SCOPE scope). Check it with: claude mcp get $NAME"
  fi
else
  echo
  say "Nothing was changed. Re-run with --register to add the server to Claude Code."
fi
