#!/bin/sh
# Harness Desk — one-line installer for macOS.   https://harnesshealth.ai/desk
#   curl -fsSL https://harnesshealth.ai/dl/install.sh | sh
# A health assistant that runs on THIS Mac: your records, the model (MedGemma, via Ollama) and
# every check stay on the machine — nothing is sent to a cloud model. Adapted from chanio.com's
# proven zero-admin installer (same shape: no sudo, private Node copy if needed, Ollama app
# fetched into ~/Applications if missing) — see chanio-com/public/install.sh for the sibling.
set -eu
BASE="${HARNESS_DESK_HOME:-$HOME/harness-desk}"
URL="https://harnesshealth.ai/dl/harness-desk.tgz"
MODEL="medgemma:4b"
say() { printf '%s\n' "$*"; }
have() { command -v "$1" >/dev/null 2>&1; }

case "$(uname -s)" in
  Darwin) ;;
  *) say "This installer is for macOS. On another OS, run desk.mjs directly with Node 24+ and Ollama — see https://harnesshealth.ai/desk"; exit 1 ;;
esac
MACOS_MAJOR=$(sw_vers -productVersion 2>/dev/null | cut -d. -f1)
if [ -n "$MACOS_MAJOR" ] && [ "$MACOS_MAJOR" -lt 14 ]; then
  say "This Mac runs macOS $(sw_vers -productVersion). The local model needs Ollama, which requires macOS 14 or newer."
  exit 1
fi
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
mkdir -p "$BASE"

# ── Node 24+ (desk.mjs uses node:sqlite): use the one you have if it qualifies, else download a
# private copy into $BASE/node — never touches a system Node, same non-destructive approach as
# chanio's installer. ──
NODE_BIN=""
if have node; then
  MAJOR=$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)
  [ "$MAJOR" -ge 24 ] && NODE_BIN="$(command -v node)"
fi
[ -z "$NODE_BIN" ] && [ -x "$BASE/node/bin/node" ] && NODE_BIN="$BASE/node/bin/node"
if [ -z "$NODE_BIN" ]; then
  case "$(uname -m)" in arm64) NARCH=arm64 ;; x86_64) NARCH=x64 ;; *) say "Unsupported CPU: $(uname -m)"; exit 1 ;; esac
  say "Node 24+ is required and wasn't found. Downloading the official Node build into $BASE/node (about 50 MB, no administrator password)…"
  TARBALL=$(curl -fsSL https://nodejs.org/dist/latest-v24.x/ | grep -oE "node-v24\.[0-9.]+-darwin-$NARCH\.tar\.gz" | head -1)
  [ -n "$TARBALL" ] || { say "Could not find the Node download. Install Node 24+ from https://nodejs.org and re-run."; exit 1; }
  curl -fSL --progress-bar "https://nodejs.org/dist/latest-v24.x/$TARBALL" -o "$TMP/node.tgz"
  rm -rf "$BASE/node"; mkdir -p "$BASE/node"
  tar -xzf "$TMP/node.tgz" -C "$BASE/node" --strip-components=1
  NODE_BIN="$BASE/node/bin/node"
  say "Node $("$NODE_BIN" -v) ready in $BASE/node."
fi

# ── Ollama: the command, or the app in /Applications or ~/Applications; else download the app ──
OLLAMA_APP=""
if [ -d "/Applications/Ollama.app" ]; then OLLAMA_APP="/Applications/Ollama.app"
elif [ -d "$HOME/Applications/Ollama.app" ]; then OLLAMA_APP="$HOME/Applications/Ollama.app"
fi
if ! have ollama && [ -z "$OLLAMA_APP" ]; then
  say "Ollama is not installed. Downloading the Ollama app into ~/Applications (about 200 MB, no administrator password)…"
  mkdir -p "$HOME/Applications"
  curl -fSL --progress-bar https://ollama.com/download/Ollama-darwin.zip -o "$TMP/ollama.zip"
  ditto -x -k "$TMP/ollama.zip" "$HOME/Applications/"
  [ -d "$HOME/Applications/Ollama.app" ] || { say "The Ollama download did not unpack. Install it from https://ollama.com/download, open it once, and re-run."; exit 1; }
  OLLAMA_APP="$HOME/Applications/Ollama.app"
  say "Ollama app ready in ~/Applications."
fi
OLLAMA_BIN="ollama"
have ollama || OLLAMA_BIN="$OLLAMA_APP/Contents/Resources/ollama"

# ── Make sure the Ollama server is actually up, then pull the model (first run only, ~3.3 GB) ──
if ! curl -fsS -o /dev/null "http://127.0.0.1:11434/api/tags" 2>/dev/null; then
  say "Starting Ollama…"
  [ -n "$OLLAMA_APP" ] && open -a "$OLLAMA_APP" 2>/dev/null || true
  have ollama && ! [ -n "$OLLAMA_APP" ] && (ollama serve >/dev/null 2>&1 &)
  i=0
  until curl -fsS -o /dev/null "http://127.0.0.1:11434/api/tags" 2>/dev/null; do
    i=$((i + 1)); [ "$i" -ge 30 ] && { say "Ollama did not start in time. Open it from Applications and re-run this installer."; exit 1; }
    sleep 1
  done
fi
if ! curl -fsS "http://127.0.0.1:11434/api/tags" 2>/dev/null | grep -q "\"$MODEL\"\|\"${MODEL%%:*}:"; then
  say "Pulling the local model ($MODEL, about 3.3 GB — first run only)…"
  "$OLLAMA_BIN" pull "$MODEL"
fi

# ── Harness Desk itself ──
say "Downloading Harness Desk…"
curl -fsSL "$URL" -o "$TMP/harness-desk.tgz"
tar -xzf "$TMP/harness-desk.tgz" -C "$BASE"
say "Installed to $BASE"
say ""

DATA_DIR="$BASE/data"
say "Starting Harness Desk…"
HARNESS_HOME="$DATA_DIR" "$NODE_BIN" "$BASE/desk/desk.mjs" &
SERVER_PID=$!
trap 'kill "$SERVER_PID" 2>/dev/null || true; rm -rf "$TMP"' EXIT INT TERM
i=0
until curl -fsS -o /dev/null "http://127.0.0.1:3760/" 2>/dev/null; do
  i=$((i + 1))
  if [ "$i" -ge 30 ]; then say "Harness Desk did not start in time. Run it by hand: HARNESS_HOME=\"$DATA_DIR\" \"$NODE_BIN\" \"$BASE/desk/desk.mjs\""; exit 1; fi
  sleep 0.5
done
say "Harness Desk is running at http://127.0.0.1:3760 — your records and the model never leave this Mac."
say "Run it again any time with: HARNESS_HOME=\"$DATA_DIR\" $NODE_BIN $BASE/desk/desk.mjs"
open "http://127.0.0.1:3760" 2>/dev/null || true
wait "$SERVER_PID"
