#!/bin/sh
# Sextant (sxt) one-line installer: downloads the server + web UI for this platform,
# installs it as an always-on service, and prints the phone pairing QR code when done.
# Supports macOS (LaunchAgent) and Linux (systemd; falls back to the built-in daemon
# when systemd is absent). Running it again = upgrade to the latest version and restart.
#
#   curl -fsSL relay.sextant.top/install | sudo sh
#
# (sudo up front: you type the password once in the first second and nothing interrupts
#  after that — the same shape as Docker's installer. Running without sudo works too: the
#  script escalates itself; with no sudo at all it falls back to ~/.local/bin.)
#
# Optional environment variables:
#   SXT_BASE=https://…   alternate download source (default: relay.sextant.top; mirrors / intranet)
#   SXT_VERSION=v0.1.0   install a specific version (default: latest)
#   GITHUB_TOKEN=...     download from a private GitHub release (development only)
set -eu

BASE="${SXT_BASE:-https://relay.sextant.top}"
REPO="${SXT_REPO:-ddos798/claude_control}"
BIN_DIR="/usr/local/bin"
SHARE_DIR="/usr/local/share/sxt"
SERVICE_NAME="sxt"

say() { printf '\033[1;36m[sxt]\033[0m %s\n' "$*"; }
die() { printf '\033[1;31m[sxt] %s\033[0m\n' "$*" >&2; exit 1; }

# ---------- Platform detection ----------
OS=$(uname -s)
case "$OS" in
  Linux)  OS=linux ;;
  Darwin) OS=darwin ;;
  *) die "Unsupported OS: $OS (Mac / Linux only)" ;;
esac
ARCH=$(uname -m)
case "$ARCH" in
  x86_64|amd64)  ARCH=amd64 ;;
  aarch64|arm64) ARCH=arm64 ;;
  *) die "Unsupported architecture: $ARCH" ;;
esac

# The service must run as the *login user* (Claude Code's login and config live in that
# user's home directory) — never as root, even when this whole script runs under sudo.
RUN_USER="${SUDO_USER:-$(id -un)}"
RUN_HOME=$(eval echo "~$RUN_USER")

SUDO=""
USERLOCAL=0
if [ "$(id -u)" -ne 0 ] && [ ! -w "$BIN_DIR" ]; then
  if command -v sudo >/dev/null 2>&1; then
    SUDO="sudo"
  else
    # No sudo is not a blocker: fall back to a per-user install (the LaunchAgent / built-in
    # daemon runs as the user anyway, so the install needs zero root). The only cost is that
    # we may have to suggest adding ~/.local/bin to PATH.
    USERLOCAL=1
    BIN_DIR="$HOME/.local/bin"
    SHARE_DIR="$HOME/.local/share/sxt"
    mkdir -p "$BIN_DIR"
    say "No root/sudo: installing to your home dir $BIN_DIR instead"
  fi
fi

# ---------- Download ----------
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
PKG="sxt_${OS}_${ARCH}.tar.gz"

if [ -n "${GITHUB_TOKEN:-}" ]; then
  # Private-repo path: look up the asset id via the API, then download (development only).
  say "Private-repo download of $PKG…"
  TAG="${SXT_VERSION:-$(curl -fsSL -H "Authorization: Bearer $GITHUB_TOKEN" \
    "https://api.github.com/repos/$REPO/releases/latest" | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -1)}"
  [ -n "$TAG" ] || die "No release found (nothing published yet?)"
  ASSET_ID=$(curl -fsSL -H "Authorization: Bearer $GITHUB_TOKEN" \
    "https://api.github.com/repos/$REPO/releases/tags/$TAG" |
    tr ',' '\n' | grep -B3 "\"name\": *\"$PKG\"" | sed -n 's/.*"id": *\([0-9]*\).*/\1/p' | head -1)
  [ -n "$ASSET_ID" ] || die "$PKG is not in release $TAG"
  curl -fSL -H "Authorization: Bearer $GITHUB_TOKEN" -H "Accept: application/octet-stream" \
    -o "$TMP/$PKG" "https://api.github.com/repos/$REPO/releases/assets/$ASSET_ID"
else
  # Official source (self-hosted, relay.sextant.top): packages live under /pkg/ per platform;
  # /pkg/<version>/ when a version is pinned.
  if [ -n "${SXT_VERSION:-}" ]; then
    URL="$BASE/pkg/$SXT_VERSION/$PKG"
  else
    URL="$BASE/pkg/$PKG"
  fi
  say "[1/3] Downloading $PKG (~5 MB)…"
  # --progress-bar: a single-line ### bar so you can see how far the download is (the one slow step).
  curl -fL --progress-bar -o "$TMP/$PKG" "$URL" || die "Download failed (network issue, or no package for this platform)"
fi

tar -xzf "$TMP/$PKG" -C "$TMP"
[ -x "$TMP/sxt" ] || die "No sxt binary in the package (corrupt download?)"

# ---------- Install files ----------
say "[2/3] Installing → $BIN_DIR"
$SUDO install -m 0755 "$TMP/sxt" "$BIN_DIR/sxt"
$SUDO mkdir -p "$SHARE_DIR"
if [ -d "$TMP/web/dist" ]; then
  $SUDO rm -rf "$SHARE_DIR/web"
  $SUDO mkdir -p "$SHARE_DIR/web"
  $SUDO cp -R "$TMP/web/dist" "$SHARE_DIR/web/dist"
fi

# ---------- Always-on service + pairing QR ----------
# Service registration lives in the binary (`sxt up`, service.go): launchd / systemd / the
# built-in daemon is chosen per platform, it is idempotent, and it prints the pairing QR at
# the end. npm, curl and manual installs all finish with this same command.
say "[3/3] Registering auto-start and launching the service…"
if [ "$OS" = "darwin" ] || [ "$USERLOCAL" = 1 ]; then
  # macOS (LaunchAgent) and per-user mode: the service must be registered as the *real* user
  # (the LaunchAgent and Claude's login config live in the user's home). Drop back to
  # $RUN_USER when the whole script is running under sudo.
  if [ "$(id -u)" -eq 0 ] && [ "$RUN_USER" != "root" ]; then
    sudo -u "$RUN_USER" "$BIN_DIR/sxt" up -web "$SHARE_DIR/web/dist"
  else
    "$BIN_DIR/sxt" up -web "$SHARE_DIR/web/dist"
  fi
else
  # Linux runs `up` as root: it writes a system-level unit; the service itself runs as
  # $RUN_USER (handled inside `up`).
  $SUDO env SUDO_USER="$RUN_USER" "$BIN_DIR/sxt" up -web "$SHARE_DIR/web/dist"
fi
if [ "$USERLOCAL" = 1 ] && ! echo ":$PATH:" | grep -q ":$BIN_DIR:"; then
  say "Tip: add  export PATH=\"\$HOME/.local/bin:\$PATH\"  to your shell config so  sxt  works everywhere."
fi
echo
say "✅ Installed! The  sxt  command works in any terminal now — no PATH setup needed ($BIN_DIR is already on PATH)."
say "Pair from the app: Settings → Connections → Add Device → Scan the QR code above."
say "Can't scan? Run  sxt code  and type the 8-digit number on your phone."
say "Away from home (4G/5G/other Wi-Fi) works too — it auto-connects via an encrypted relay, no public IP or port-forwarding needed."
say "Handy commands: sxt qr (show QR again) · sxt code (pairing code) · sxt status · sxt logs · web UI: http://<your-IP>:7280/"
say "Want the desktop  claude  command to follow the account you set as current in the phone app? Add  eval \"\$(sxt shell-init)\"  to ~/.zshrc or ~/.bashrc."
