#!/usr/bin/env bash
# Upgrade Grok Bot on Arch/Omarchy.
# Prefer AUR grok-bot-bin when it matches Cursor stable.
# If AUR lags, install the official .deb via makepkg (pacman-tracked).
set -euo pipefail

HELPERS="$(cd "$(dirname "$0")" && pwd)/grok-bot-upgrade-helpers"
WORKDIR="${TMPDIR:-/tmp}/grok-bot-upgrade-$$"

ver_ge() {
  # true if $1 >= $2 (x.y.z)
  printf '%s\n%s\n' "$2" "$1" | sort -V | head -1 | grep -qx "$2"
}

installed_version() {
  if pacman -Q grok-bot-bin >/dev/null 2>&1; then
    pacman -Q grok-bot-bin | awk '{print $2}' | sed 's/-.*//'
  elif pacman -Q grok-bot >/dev/null 2>&1; then
    pacman -Q grok-bot | awk '{print $2}' | sed 's/-.*//'
  else
    echo "0"
  fi
}

aur_version() {
  yay -Si grok-bot-bin 2>/dev/null | awk -F' *: *' '/^Version/{print $2; exit}' | sed 's/-.*//' || true
}

official_meta() {
  python3 - <<'PY'
import json, urllib.request, uuid, re, sys
mid = str(uuid.uuid4())
url = f"https://api2.cursor.sh/updates/api/update/linux-x64/sand/0.1.0/{mid}/stable"
req = urllib.request.Request(url, headers={"User-Agent": "upgrade-grok-bot/1.1"})
with urllib.request.urlopen(req, timeout=30) as r:
    d = json.loads(r.read().decode())
ver = d.get("productVersion") or d.get("version")
u = d.get("url") or ""
m = re.search(r"/([0-9a-f]{40})/", u)
if not ver or not m:
    print("failed to parse official release", ver, u, file=sys.stderr)
    sys.exit(2)
commit = m.group(1)
deb = f"https://downloads.cursor.com/grokbot/stable/{commit}/linux/x64/grok-bot_{ver}_amd64.deb"
print(ver)
print(commit)
print(deb)
PY
}

backup_config() {
  mkdir -p ~/backups
  local stamp=~/backups/"Grok-Bot-config-$(date +%F)"
  if [[ ! -d "$stamp" ]]; then
    cp -a ~/.config/"Grok Bot" "$stamp" || true
  fi
  echo "Config backup: $stamp"
}

quit_app() {
  echo "Quitting Grok Bot (this chat dies if still open)..."
  pkill -TERM -f '/opt/Grok Bot/grok-bot' 2>/dev/null || true
  sleep 2
  if pgrep -af '/opt/Grok Bot/grok-bot' >/dev/null; then
    pkill -KILL -f '/opt/Grok Bot/grok-bot' 2>/dev/null || true
    sleep 1
  fi
  if pgrep -af '/opt/Grok Bot/grok-bot' >/dev/null; then
    echo "Could not stop Grok Bot; abort."
    exit 1
  fi
  echo "grok-bot stopped"
}

install_via_aur() {
  echo "AUR grok-bot-bin is current enough — using yay..."
  yay -S grok-bot-bin --answerclean N --answerdiff N --answeredit N
}

install_via_official() {
  local ver="$1"
  local deb_url="$3"
  echo "AUR lags. Installing official ${ver} from Cursor CDN via makepkg..."
  mkdir -p "$WORKDIR"
  cd "$WORKDIR"
  curl -fL --retry 3 -o "grok-bot_${ver}_amd64.deb" "$deb_url"
  local sum
  sum="$(sha256sum "grok-bot_${ver}_amd64.deb" | awk '{print $1}')"

  if [[ -f "$HELPERS/grok-bot.sh" ]]; then
    cp "$HELPERS/grok-bot.sh" ./grok-bot.sh
  else
    cat > grok-bot.sh << 'EOS'
#!/bin/sh
export FONTCONFIG_NO_CHECK_CACHE_VERSION=1
exec "/opt/Grok Bot/grok-bot" "$@"
EOS
  fi
  chmod +x grok-bot.sh

  cat > PKGBUILD <<PKG
pkgname=grok-bot-bin
pkgver=${ver}
pkgrel=1
pkgdesc='Grok Bot desktop agent (official deb via upgrade-grok-bot.sh)'
arch=('x86_64')
url='https://cursor.com'
license=('LicenseRef-Proprietary')
depends=(gtk3 libnotify nss libxss libxtst xdg-utils at-spi2-core util-linux-libs libsecret hicolor-icon-theme alsa-lib libappindicator)
provides=('sand' 'grok-bot')
conflicts=('sand' 'grok-bot' 'grokbot-linux-port' 'grokbot-linux-port-bin')
replaces=('grok-bot')
options=('!strip' '!debug')
source=(
  "grok-bot_\${pkgver}_amd64.deb"
  grok-bot.sh
)
sha256sums=('${sum}' 'SKIP')
noextract=("grok-bot_\${pkgver}_amd64.deb")
package() {
  bsdtar -O -xf "grok-bot_\${pkgver}_amd64.deb" data.tar.xz | bsdtar -C "\${pkgdir}" -xJf -
  local _res="\${pkgdir}/opt/Grok Bot/resources"
  if [[ -f "\${_res}/apparmor-profile" ]]; then
    install -Dm644 "\${_res}/apparmor-profile" "\${pkgdir}/etc/apparmor.d/grok-bot"
  fi
  install -Dm755 grok-bot.sh "\${pkgdir}/usr/bin/grok-bot"
  ln -sf grok-bot "\${pkgdir}/usr/bin/sand"
  if [[ -f "\${pkgdir}/usr/share/applications/grok-bot.desktop" ]]; then
    sed -i 's|^Exec=.*|Exec=grok-bot %U|' "\${pkgdir}/usr/share/applications/grok-bot.desktop"
  fi
  rm -rf "\${pkgdir}/usr/share/doc"
}
PKG

  makepkg -si --noconfirm
  cd /
  rm -rf "$WORKDIR"
}

verify() {
  echo "Verify:"
  pacman -Qi grok-bot-bin 2>/dev/null | rg -i '^(Name|Version)' || true
  ls -l /usr/bin/grok-bot /usr/bin/sand
  test -d ~/.config/"Grok Bot" && echo "config intact"
  echo "Done. Launch with: grok-bot"
}

main() {
  echo "== Grok Bot upgrade (AUR or official when AUR lags) =="
  backup_config

  mapfile -t meta < <(official_meta)
  local official="${meta[0]}"
  local commit="${meta[1]}"
  local deb_url="${meta[2]}"
  local installed aur
  installed="$(installed_version)"
  aur="$(aur_version)"
  echo "Installed: ${installed}"
  echo "AUR:       ${aur:-unknown}"
  echo "Official:  ${official}"

  if ver_ge "$installed" "$official"; then
    echo "Already on official-or-newer (${installed}). Nothing to do."
    exit 0
  fi

  quit_app

  if [[ -n "$aur" ]] && ver_ge "$aur" "$official"; then
    install_via_aur
  else
    echo "AUR (${aur:-none}) behind official ${official}."
    install_via_official "$official" "$commit" "$deb_url"
  fi

  verify
}

# Only run when executed, never when sourced
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  main "$@"
fi
