#!/usr/bin/env bash
# Idempotent remote bootstrap for an Agentic Remote Development server.
# Run by `agentic server setup <name>` via:  ssh <server> bash -s < bootstrap.sh
# Safe to re-run: every step checks before installing.
set -euo pipefail

log()  { printf '\033[1;36m▶ %s\033[0m\n' "$*"; }
ok()   { printf '\033[0;32m  ✓ %s\033[0m\n' "$*"; }
warn() { printf '\033[0;33m  ⚠ %s\033[0m\n' "$*"; }
have() { command -v "$1" >/dev/null 2>&1; }

# ── package manager detection ────────────────────────────────────────────────
PKG=""
if   have apt-get; then PKG="apt"
elif have dnf;     then PKG="dnf"
elif have brew;    then PKG="brew"
else warn "No supported package manager (apt/dnf/brew) — install deps manually."; fi

pkg_install() {
  local p="$1"
  case "$PKG" in
    apt)  sudo apt-get update -qq && sudo apt-get install -y "$p" ;;
    dnf)  sudo dnf install -y "$p" ;;
    brew) brew install "$p" ;;
    *)    warn "cannot auto-install $p"; return 1 ;;
  esac
}

ensure() {  # ensure <binary> [package-name]
  local bin="$1" pkg="${2:-$1}"
  if have "$bin"; then ok "$bin present"; else log "installing $pkg"; pkg_install "$pkg" && ok "$bin installed"; fi
}

# ── core tooling ─────────────────────────────────────────────────────────────
log "Core tooling"
ensure git
ensure tmux
ensure rsync
ensure curl

# Node ≥ 22 (NodeSource on apt/dnf; brew otherwise). 22 (not 20) because some
# agent CLIs need it — e.g. pi's bundled undici crashes on Node 20.
if have node && [ "$(node -p 'process.versions.node.split(".")[0]')" -ge 22 ] 2>/dev/null; then
  ok "node $(node -v)"
else
  log "installing Node 22"
  case "$PKG" in
    apt) curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs ;;
    dnf) curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo -E bash - && sudo dnf install -y nodejs ;;
    brew) brew install node@22 ;;
    *) warn "install Node ≥ 22 manually" ;;
  esac
  have node && ok "node $(node -v)"
fi

# GitHub CLI
if have gh; then ok "gh present"; else
  log "installing gh"
  case "$PKG" in
    apt) (type -p wget >/dev/null || sudo apt-get install -y wget) \
         && sudo mkdir -p -m 755 /etc/apt/keyrings \
         && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg >/dev/null \
         && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
         && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list >/dev/null \
         && sudo apt-get update -qq && sudo apt-get install -y gh ;;
    dnf) sudo dnf install -y 'dnf-command(config-manager)' && sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo && sudo dnf install -y gh ;;
    brew) brew install gh ;;
    *) warn "install gh manually" ;;
  esac
  have gh && ok "gh installed"
fi

# Docker + compose plugin (for the observability stack)
if have docker; then ok "docker present"; else
  log "installing docker"
  if [ "$PKG" = "brew" ]; then warn "install Docker Desktop manually on macOS"; else
    curl -fsSL https://get.docker.com | sudo sh && sudo usermod -aG docker "$USER" || warn "docker install needs manual follow-up"
  fi
fi

# ── agentic CLI (clone + build from git; alpha is not published to npm) ───────
# One shared clone, built in place, exposed via a symlink on every user's PATH.
# `agentic upgrade` later re-pulls + rebuilds it — one build updates all users.
AGENTIC_REPO="${AGENTIC_REPO:-inspiraCode/agentic-workflow}"
AGENTIC_SRC="${AGENTIC_SRC:-/opt/agentic-workflow}"
log "agentic CLI ($AGENTIC_REPO → $AGENTIC_SRC)"

# pnpm via corepack (ships with Node ≥ 20) — it honours the repo's
# `packageManager` pin (pnpm 9, matching the v9 lockfile). Fallback pins the
# major so we never grab pnpm 10 (stricter workspace parsing + build gate).
if corepack enable 2>/dev/null; then ok "pnpm enabled (corepack)"; elif have pnpm; then ok "pnpm present"; else
  npm i -g pnpm@9 && ok "pnpm installed"
fi

# Clone (or update) into the shared location. `gh repo clone` handles private
# repos via the gh auth set up below; fall back to plain git for public repos.
if [ -d "$AGENTIC_SRC/.git" ]; then
  git -C "$AGENTIC_SRC" pull --ff-only && ok "source updated"
else
  sudo mkdir -p "$AGENTIC_SRC" && sudo chown "$(id -un):$(id -gn)" "$AGENTIC_SRC"
  if have gh && gh auth status >/dev/null 2>&1; then
    gh repo clone "$AGENTIC_REPO" "$AGENTIC_SRC" && ok "cloned (gh)"
  else
    git clone "https://github.com/${AGENTIC_REPO}.git" "$AGENTIC_SRC" && ok "cloned (git)"
  fi
fi

log "building agentic CLI"
( cd "$AGENTIC_SRC" && pnpm install && pnpm build ) && ok "built"
chmod +x "$AGENTIC_SRC/dist/cli.js"
sudo ln -sf "$AGENTIC_SRC/dist/cli.js" /usr/local/bin/agentic && ok "linked /usr/local/bin/agentic"
have agentic && ok "agentic $(agentic --version 2>/dev/null || echo present)"

agentic shell install >/dev/null 2>&1 && ok "shell aliases installed" || warn "could not install shell aliases"

# ── auth + repos (human follow-up where needed) ──────────────────────────────
log "GitHub auth"
if gh auth status >/dev/null 2>&1; then ok "gh authenticated"; else
  warn "gh is NOT authenticated — run:  gh auth login  (needs repo, project, workflow scopes)"
fi

cat <<'NEXT'

────────────────────────────────────────────────────────────
Bootstrap complete. Remaining manual steps (one-time):
  1. gh auth login            # if not already authenticated
  2. clone your solution repos into the server's workdir, then
     agentic solution register <path>   (or copy your solution dir up)
  3. agentic server up <name> # from your laptop: start redis/loki/grafana
Then drive it from your laptop:
  agentic server run <name> -- dev loop
────────────────────────────────────────────────────────────
NEXT
