#!/usr/bin/env bash
# Agentic AI Architect — setup preflight (macOS / Linux)
#
#   ./setup-check.sh            # check only, with install guidance
#   ./setup-check.sh --install  # also try to install the missing auto-installable tools
#   ./setup-check.sh --strict   # treat warnings as failures too (exit 1) — for facilitators
#
# Checks what the labs actually need. Antigravity, accounts, and Ollama can't be
# auto-installed — the script links/guides for those.

set -uo pipefail
DO_INSTALL=0; STRICT=0
for a in "$@"; do
  case "$a" in
    --install) DO_INSTALL=1 ;;
    --strict)  STRICT=1 ;;
  esac
done

if [ -t 1 ]; then G=$'\e[32m'; Y=$'\e[33m'; R=$'\e[31m'; B=$'\e[1m'; D=$'\e[2m'; X=$'\e[0m'; else G= Y= R= B= D= X=; fi

OS="$(uname -s)"
case "$OS" in
  Darwin) OSNAME="macOS"; PM="brew" ;;
  Linux)  OSNAME="Linux"
          if command -v apt-get >/dev/null 2>&1; then PM="apt"
          elif command -v dnf >/dev/null 2>&1; then PM="dnf"
          elif command -v pacman >/dev/null 2>&1; then PM="pacman"
          else PM=""; fi ;;
  *)      OSNAME="$OS"; PM="" ;;
esac

PASS=0; WARN=0; FAIL=0
ok()   { printf "  ${G}✓${X} %s\n" "$1"; PASS=$((PASS+1)); }
warn() { printf "  ${Y}⚠${X} %s\n" "$1"; WARN=$((WARN+1)); }
bad()  { printf "  ${R}✗${X} %s\n" "$1"; FAIL=$((FAIL+1)); }
hint() { printf "      ${D}↳ %s${X}\n" "$1"; }

maybe_install() { # $1 = human name, $2.. = command to run
  [ "$DO_INSTALL" = "1" ] || { hint "to install: $*"; return 1; }
  shift; printf "      ${B}installing…${X} %s\n" "$*"
  if "$@"; then return 0; else hint "install failed — run it manually"; return 1; fi
}

printf "\n${B}Agentic AI Architect — setup check${X}  ${D}(%s, pkg-mgr: %s)${X}\n\n" "$OSNAME" "${PM:-none}"

# ── Node.js >= 20 (critical) ────────────────────────────────────────────────
printf "${B}Core toolchain${X}\n"
if command -v node >/dev/null 2>&1; then
  V=$(node -v | sed 's/^v//'); MAJ=${V%%.*}
  if [ "${MAJ:-0}" -ge 20 ] 2>/dev/null; then ok "Node.js v$V"
  else
    bad "Node.js v$V — need v20 or newer"
    case "$PM" in
      brew) maybe_install "Node 20" brew install node@20 ;;
      apt)  hint "apt's node is old — install LTS via nvm: https://github.com/nvm-sh/nvm  then: nvm install --lts" ;;
      *)    hint "install Node 20 LTS from https://nodejs.org/en/download" ;;
    esac
  fi
else
  bad "Node.js not found"
  case "$PM" in
    brew) maybe_install "Node 20" brew install node@20 ;;
    apt)  hint "install LTS via nvm (apt's is old): https://github.com/nvm-sh/nvm" ;;
    dnf)  maybe_install "Node" sudo dnf install -y nodejs ;;
    *)    hint "install Node 20 LTS from https://nodejs.org/en/download" ;;
  esac
fi

command -v npm  >/dev/null 2>&1 && ok "npm v$(npm -v)"   || bad "npm not found (comes with Node.js)"
command -v npx  >/dev/null 2>&1 && ok "npx present"      || bad "npx not found (comes with npm)"

# ── git (critical) ──────────────────────────────────────────────────────────
if command -v git >/dev/null 2>&1; then ok "git $(git --version | awk '{print $3}')"
else
  bad "git not found"
  case "$PM" in
    brew) maybe_install "git" brew install git ;;
    apt)  maybe_install "git" sudo apt-get install -y git ;;
    dnf)  maybe_install "git" sudo dnf install -y git ;;
    pacman) maybe_install "git" sudo pacman -S --noconfirm git ;;
    *)    hint "install git from https://git-scm.com/downloads" ;;
  esac
fi
# GitHub identity / auth (info)
if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then ok "GitHub CLI authenticated"
elif git config user.email >/dev/null 2>&1; then ok "git identity set ($(git config user.email))"
else warn "no git identity yet — git config --global user.email you@example.com (+ a GitHub account to push)"; fi

# ── uv / uvx (DuckDuckGo MCP server in Lab 1) ───────────────────────────────
printf "\n${B}MCP / lab tooling${X}\n"
if command -v uvx >/dev/null 2>&1; then ok "uv / uvx $(uv --version 2>/dev/null | awk '{print $2}')"
else
  warn "uv / uvx not found — needed for the DuckDuckGo search server (Lab 1)"
  hint "the offline mock-search server is the fallback, so this is not blocking"
  maybe_install "uv" sh -c 'curl -LsSf https://astral.sh/uv/install.sh | sh'
fi

# ── Antigravity (host — manual) ─────────────────────────────────────────────
if command -v agy >/dev/null 2>&1; then ok "Antigravity CLI (agy) on PATH"
else warn "Antigravity not detected — install the App + CLI (the workshop host); can't be auto-installed"; fi

# ── network + ports ─────────────────────────────────────────────────────────
printf "\n${B}Environment${X}\n"
if command -v npm >/dev/null 2>&1 && npm ping >/dev/null 2>&1; then ok "npm registry reachable"
else warn "npm registry not reachable — check network/proxy (labs have offline fallbacks)"; fi
for P in 3000 3001; do
  if command -v lsof >/dev/null 2>&1 && lsof -iTCP:"$P" -sTCP:LISTEN >/dev/null 2>&1; then
    warn "port $P is in use (Day-2 app needs it free)"
  else ok "port $P free"; fi
done

# ── summary ─────────────────────────────────────────────────────────────────
printf "\n${B}Summary:${X} ${G}%s ok${X} · ${Y}%s warn${X} · ${R}%s missing${X}\n" "$PASS" "$WARN" "$FAIL"
if [ "$FAIL" -gt 0 ]; then
  printf "  Fix the ${R}✗${X} items above, then re-run."
  [ "$DO_INSTALL" = "0" ] && printf "  Tip: ${B}./setup-check.sh --install${X} auto-installs what it can."
  printf "\n\n"; exit 1
fi
if [ "$WARN" -gt 0 ]; then
  if [ "$STRICT" = "1" ]; then
    printf "  ${R}Not ready (strict):${X} resolve the %s warning(s) above (Antigravity, uv, ports, git identity).\n\n" "$WARN"
    exit 1
  fi
  printf "  ${G}Core toolchain OK${X} — review the %s warning(s) above. Manual items: Antigravity signed in, a GitHub account.\n\n" "$WARN"
  exit 0
fi
printf "  ${G}All green — you're ready.${X}\n\n"
exit 0
