#!/bin/bash
# omniroute-update: обновить/проверить OmniRoute на mini и/или MacBook.
# Пароль (sudo на mini) НЕ хранится: передавать через env OMNIROUTE_SUDO_PASS
# только на время вызова, либо ввести по запросу. См. SKILL.md и Obsidian
# Projects/omniroute/ (Decisions D1, D4).
set -euo pipefail

MINI="cebers_mini@100.84.177.25"
SSH="ssh -i $HOME/.ssh/id_ed25519 -p 2222 $MINI"
VERSION=""; TARGETS=""; VERIFY_ONLY=0

usage() {
  cat <<EOF
usage: update.sh [--version X.Y.Z] [--verify-only] [mini|local|all]
  --version      целевая версия (default: npm view omniroute version)
  --verify-only  только проверка здоровья, без обновления
  цель           mini | local (MacBook) | all (default: all)
Пароль sudo для mini: env OMNIROUTE_SUDO_PASS, иначе спросит интерактивно.
EOF
  exit 0
}

while [ $# -gt 0 ]; do
  case "$1" in
    --version) VERSION="$2"; shift 2;;
    --verify-only) VERIFY_ONLY=1; shift;;
    -h|--help) usage;;
    mini|local|all) TARGETS="$1"; shift;;
    *) echo "неизвестный аргумент: $1"; exit 1;;
  esac
done
TARGETS="${TARGETS:-all}"

need_pass() {
  if [ -z "${OMNIROUTE_SUDO_PASS:-}" ]; then
    read -r -s -p "sudo-пароль mini (не сохраняется): " OMNIROUTE_SUDO_PASS; echo
  fi
}

verify_instance() { # $1 = "local" | "mini"
  local runner="bash -c"
  [ "$1" = "mini" ] && runner="$SSH"
  echo "--- verify [$1]"
  # mini: ключ в ~/.codex/omniroute.env; MacBook: ключей-файла нет — берём
  # первый API-ключ из локальной БД инстанса на лету (не сохраняется).
  $runner 'set -a; . ~/.codex/omniroute.env 2>/dev/null; set +a
    if [ -z "${OMNIROUTE_API_KEY:-}" ] && [ -r "$HOME/.local/share/omniroute-app/data/storage.sqlite" ]; then
      OMNIROUTE_API_KEY=$(sqlite3 -readonly "$HOME/.local/share/omniroute-app/data/storage.sqlite" "SELECT key FROM api_keys LIMIT 1" 2>/dev/null)
    fi
    # /v1/models на 20128: порт 20127 МЁРТВ с июня 2026 (мост удалён как виновник
    # зависаний codex) — стук туда давал гарантированный ложный провал верификации.
    m=$(curl -s -o /dev/null -w "%{http_code}" --max-time 15 http://127.0.0.1:20128/v1/models -H "Authorization: Bearer ${OMNIROUTE_API_KEY:-}")
    l=$(curl -s -o /dev/null -w "%{http_code}" --max-time 15 http://127.0.0.1:20129/login)
    # auto/best-fast есть на обоих инстансах независимо от набора провайдеров.
    # 120 с, а не 60: латентность маршрутизации гуляет (2-70 с) и 60 давало ложный провал.
    c=$(curl -s -o /dev/null -w "%{http_code}" --max-time 120 http://127.0.0.1:20128/v1/chat/completions -H "Authorization: Bearer ${OMNIROUTE_API_KEY:-}" -H "Content-Type: application/json" -d "{\"model\":\"auto/best-fast\",\"messages\":[{\"role\":\"user\",\"content\":\"ok\"}],\"max_tokens\":8}")
    echo "models:$m login:$l chat:$c"
    [ "$m" = 200 ] && [ "$l" = 200 ] && [ "$c" = 200 ] && echo "VERIFY OK" || { echo "VERIFY FAIL"; exit 1; }'
}

update_local() {
  echo "=== MacBook: обновление до $VERSION"
  ( cd "$HOME/.local/share/omniroute-app" && npm install "omniroute@$VERSION" >/dev/null 2>&1 || {
      rm -rf "$HOME/.local/share/omniroute-app/node_modules/.omniroute-"* 2>/dev/null || true
      cd "$HOME/.local/share/omniroute-app" && npm install "omniroute@$VERSION"; } )
  export PATH=/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:$PATH
  npm install -g "omniroute@$VERSION" >/dev/null 2>&1 || {
    rm -rf /opt/homebrew/lib/node_modules/.omniroute-* 2>/dev/null || true
    npm install -g "omniroute@$VERSION"; }
  python3 -c "import json; print('app-local:', json.load(open('$HOME/.local/share/omniroute-app/node_modules/omniroute/package.json'))['version'])"
  # npm install затирает dist/.../build/Release — вернуть нативный better-sqlite3
  # ДО рестарта, иначе процесс поднимется на JS-фолбэке (см. SKILL.md, Грабли).
  "$(dirname "$0")/fix_native.sh" local ||
    echo "ВНИМАНИЕ: нативный better-sqlite3 не восстановлен — шина поднимется на JS-фолбэке"
  launchctl kickstart -k "gui/$(id -u)/com.cebers.omniroute"
  sleep 25
  verify_instance local
}

update_mini() {
  need_pass
  echo "=== mini: бэкап БД + обновление до $VERSION"
  $SSH "echo '$OMNIROUTE_SUDO_PASS' | sudo -S -p '' sqlite3 /Users/omniroute_svc/.local/share/omniroute-app/data/storage.sqlite \".backup /Users/omniroute_svc/.local/share/omniroute-app/data/db_backups/pre-$VERSION-\$(date +%Y%m%d-%H%M%S).sqlite\" && echo BACKUP_OK"
  $SSH "export PATH=/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:\$PATH
    npm install -g omniroute@$VERSION >/dev/null 2>&1 || { rm -rf /opt/homebrew/lib/node_modules/.omniroute-* 2>/dev/null; npm install -g omniroute@$VERSION; }
    python3 -c \"import json; print('mini global:', json.load(open('/opt/homebrew/lib/node_modules/omniroute/package.json'))['version'])\""
  # npm install затирает dist/.../build/Release — вернуть нативный better-sqlite3
  # ДО рестарта, иначе процесс поднимется на JS-фолбэке (см. SKILL.md, Грабли).
  MINI_SUDO_PASS="$OMNIROUTE_SUDO_PASS" "$(dirname "$0")/fix_native.sh" mini ||
    echo "ВНИМАНИЕ: нативный better-sqlite3 не восстановлен — шина поднимется на JS-фолбэке"
  $SSH "echo '$OMNIROUTE_SUDO_PASS' | sudo -S -p '' launchctl kickstart -k system/com.cebers.omniroute && echo KICKED"
  sleep 30
  verify_instance mini
}

if [ "$VERIFY_ONLY" = 1 ]; then
  [ "$TARGETS" != "local" ] && verify_instance mini
  [ "$TARGETS" != "mini" ] && verify_instance local
  exit 0
fi

if [ -z "$VERSION" ]; then
  export PATH=/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:$PATH
  VERSION=$(npm view omniroute version)
  echo "целевая версия (npm latest): $VERSION"
fi

[ "$TARGETS" != "local" ] && update_mini
[ "$TARGETS" != "mini" ] && update_local
echo "ГОТОВО. Не забудь строку в Obsidian Projects/omniroute/Changelog.md"
