#!/bin/sh
# Sextant(sxt)一键安装:下载对应平台的服务端 + 网页端,装成常驻服务,装完直接
# 显示手机配对二维码。支持 Mac(LaunchAgent)与 Linux(systemd;无 systemd 时用
# 内置守护进程)。重复运行 = 升级到最新版并重启服务。
#
#   curl -fsSL relay.sextant.top/install | sudo sh
#
# (sudo 放前面:密码第一秒就输,后面全程不打断 —— Docker 同款姿势。不带 sudo
#  直接跑也行:脚本会自己提权;连 sudo 都没有就降级装到 ~/.local/bin。)
#
# 用户可见输出跟随 shell 语言(LC_ALL/LC_MESSAGES/LANG 含 zh → 中文,否则英文),
# 与二进制自身的双语横幅(main.go tr / version.go bannerZH)一致。
#
# 可选环境变量:
#   SXT_BASE=https://…   换下载源(默认官方 relay.sextant.top;镜像/内网分发用)
#   SXT_VERSION=v0.1.0   装指定版本(默认最新)
#   GITHUB_TOKEN=...     从私有 GitHub 仓库 release 下载(仅开发期用)
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"

# Bilingual output: Chinese when the shell locale looks like zh*, English otherwise.
# (NOT named `tr` — that shadows the tr(1) command this script uses below.)
_LOC="${LC_ALL:-${LC_MESSAGES:-${LANG:-}}}"
case "$_LOC" in *[Zz][Hh]*) SXT_ZH=1 ;; *) SXT_ZH=0 ;; esac
L() { if [ "$SXT_ZH" = 1 ]; then printf '%s' "$1"; else printf '%s' "$2"; fi; }

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

# ---------- 平台检测 ----------
OS=$(uname -s)
case "$OS" in
  Linux)  OS=linux ;;
  Darwin) OS=darwin ;;
  *) die "$(L "暂不支持的系统: $OS(目前支持 Mac / Linux)" "Unsupported OS: $OS (Mac / Linux only)")" ;;
esac
ARCH=$(uname -m)
case "$ARCH" in
  x86_64|amd64)  ARCH=amd64 ;;
  aarch64|arm64) ARCH=arm64 ;;
  *) die "$(L "暂不支持的架构: $ARCH" "Unsupported architecture: $ARCH")" ;;
esac

# 服务要以「登录用户」身份跑(Claude Code 的登录/配置在该用户家目录),
# 即使整个脚本是 sudo 执行的也不能变成 root。
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
    # 没有 sudo 也不拦路:降级装到用户目录(LaunchAgent/内置守护进程本就按用户跑,
    # 零 root 完成安装)。唯一代价是可能要提示把 ~/.local/bin 加进 PATH。
    USERLOCAL=1
    BIN_DIR="$HOME/.local/bin"
    SHARE_DIR="$HOME/.local/share/sxt"
    mkdir -p "$BIN_DIR"
    say "$(L "无 root/sudo:改为安装到用户目录 $BIN_DIR" "No root/sudo: installing to your home dir $BIN_DIR instead")"
  fi
fi

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

if [ -n "${GITHUB_TOKEN:-}" ]; then
  # 私有仓库路径:走 API 找 asset id 再下载(仅开发期用)。
  say "$(L "私有仓库模式下载 $PKG…" "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 "$(L "找不到 release(仓库还没发过版?)" "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 "$(L "release $TAG 里没有 $PKG" "$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
  # 官方源(自建,relay.sextant.top):/pkg/ 下按平台放包;带版本时走 /pkg/<版本>/。
  if [ -n "${SXT_VERSION:-}" ]; then
    URL="$BASE/pkg/$SXT_VERSION/$PKG"
  else
    URL="$BASE/pkg/$PKG"
  fi
  say "[1/3] $(L "下载 $PKG(约 5 MB)…" "Downloading $PKG (~5 MB)…")"
  # --progress-bar:单行 ### 进度条,用户能看到下载走到哪了(这是安装唯一的耗时点)。
  curl -fL --progress-bar -o "$TMP/$PKG" "$URL" || die "$(L "下载失败(网络问题,或该平台没有发布包)" "Download failed (network issue, or no package for this platform)")"
fi

tar -xzf "$TMP/$PKG" -C "$TMP"
[ -x "$TMP/sxt" ] || die "$(L "包里没有 sxt 二进制(包损坏?)" "No sxt binary in the package (corrupt download?)")"

# ---------- 安装文件 ----------
say "[2/3] $(L "安装 → $BIN_DIR" "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

# ---------- 常驻服务 + 配对二维码 ----------
# 服务注册逻辑在二进制里(`sxt up`,service.go):launchd / systemd / 内置守护进程
# 按平台自动选,幂等,收尾直接打印配对二维码。npm / curl / 手动装完全走同一句。
say "[3/3] $(L "注册开机自启并启动服务…" "Registering auto-start and launching the service…")"
if [ "$OS" = "darwin" ] || [ "$USERLOCAL" = 1 ]; then
  # macOS(LaunchAgent) 与用户目录模式:服务必须以「真实用户」身份注册(LaunchAgent
  # 和 Claude 的登录配置都在用户家目录)。整个脚本被 sudo 执行时降回 $RUN_USER。
  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 用 root 跑 up:写系统级 unit,服务以 $RUN_USER 身份运行(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 "$(L "提示:把  export PATH=\"\$HOME/.local/bin:\$PATH\"  加进你的 shell 配置,sxt 命令才随处可用。" "Tip: add  export PATH=\"\$HOME/.local/bin:\$PATH\"  to your shell config so  sxt  works everywhere.")"
fi
echo
say "$(L "✅ 安装完成!sxt 命令已可在任意终端直接使用,无需配置环境变量($BIN_DIR 已在 PATH)。" "✅ Installed! The  sxt  command works in any terminal now — no PATH setup needed ($BIN_DIR is already on PATH).")"
say "$(L "手机 App「设置 → 连接管理 → 添加设备 → 扫码」上面的二维码即可配对;" "Pair from the app: Settings → Connections → Add Device → Scan the QR code above.")"
say "$(L "不方便扫码就敲  sxt code  ,手机上输 8 位数字。" "Can't scan? Run  sxt code  and type the 8-digit number on your phone.")"
say "$(L "在外面(4G/5G/别的 WiFi)也能直接用 —— 已自动接入加密中转,无需公网 IP/开端口。" "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 "$(L "常用命令:sxt qr(重显二维码) · sxt code(配对码) · sxt status · sxt logs · 网页版: http://<本机IP>:7280/" "Handy commands: sxt qr (show QR again) · sxt code (pairing code) · sxt status · sxt logs · web UI: http://<your-IP>:7280/")"
