#!/bin/sh
# goglobal-proxy-routing Skill installer (POSIX sh; macOS / Linux / WSL).
# It ONLY: downloads the tarball + .sha256, verifies SHA-256, extracts to a temp dir,
# and copies skills/goglobal-proxy-routing into your agent skill dir(s). It runs nothing else.
#
#   curl -fsSL https://www.paibaowork.com/skills/goglobal-proxy-routing/install.sh | sh
#   curl -fsSL https://www.paibaowork.com/skills/goglobal-proxy-routing/install.sh | sh -s -- --agent all
#
# Options:
#   --agent claude|agents|all   claude = ~/.claude/skills (Claude Code; $CLAUDE_CONFIG_DIR/skills if set)
#                               agents = ~/.agents/skills (Codex, Cursor, OpenCode, GitHub Copilot, generic)
#                               all    = both
#   --version vYYYY.MM.DD       install a pinned version instead of latest
#   --sha256 <hex>              also require this exact SHA-256 (e.g. copied from the web page)
#   --file <tar.gz>             offline: use a local tarball (needs <file>.sha256 next to it, or --sha256)
#   -h | --help
set -eu

BASE="https://www.paibaowork.com/skills/goglobal-proxy-routing"
NAME="goglobal-proxy-routing"
TARBALL="goglobal-proxy-skill.tar.gz"
AGENT="${GGPR_AGENT:-}"
VERSION=""
WANT_SHA=""
LOCAL_FILE=""

say() { printf '%s\n' "$*"; }
die() { printf '错误 / error: %s\n' "$*" >&2; exit 1; }

while [ $# -gt 0 ]; do
  case "$1" in
    --agent) [ $# -ge 2 ] || die "--agent needs a value"; AGENT="$2"; shift 2 ;;
    --agent=*) AGENT="${1#*=}"; shift ;;
    --version) [ $# -ge 2 ] || die "--version needs a value"; VERSION="$2"; shift 2 ;;
    --version=*) VERSION="${1#*=}"; shift ;;
    --sha256) [ $# -ge 2 ] || die "--sha256 needs a value"; WANT_SHA="$2"; shift 2 ;;
    --sha256=*) WANT_SHA="${1#*=}"; shift ;;
    --file) [ $# -ge 2 ] || die "--file needs a value"; LOCAL_FILE="$2"; shift 2 ;;
    --file=*) LOCAL_FILE="${1#*=}"; shift ;;
    -h|--help) sed -n '2,19p' "$0" 2>/dev/null || say "see https://www.paibaowork.com/skills/goglobal-proxy-routing/"; exit 0 ;;
    *) die "unknown option: $1" ;;
  esac
done

if [ -n "$VERSION" ]; then
  case "$VERSION" in v[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]|v[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9].[0-9]*) ;; *) die "bad --version: $VERSION" ;; esac
  URL_BASE="$BASE/$VERSION"
else
  URL_BASE="$BASE/latest"
fi
if [ -n "$WANT_SHA" ]; then
  WANT_SHA=$(printf '%s' "$WANT_SHA" | tr 'A-F' 'a-f')
  case "$WANT_SHA" in *[!0-9a-f]*) die "--sha256 must be 64 hex chars" ;; esac
  [ ${#WANT_SHA} -eq 64 ] || die "--sha256 must be 64 hex chars"
fi

[ -n "${HOME:-}" ] || die "HOME is not set"
CLAUDE_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills"
AGENTS_DIR="$HOME/.agents/skills"

# --- choose target(s) ------------------------------------------------------
if [ -z "$AGENT" ]; then
  if [ -r /dev/tty ] && (exec </dev/tty) 2>/dev/null; then
    say "装到哪个智能体？ / Install for which agent?"
    say "  1) Claude Code            -> $CLAUDE_DIR"
    say "  2) Codex/Cursor/OpenCode/Copilot/其他 -> $AGENTS_DIR"
    say "  3) 两个都装 / both  (默认 default)"
    printf '输入 1/2/3 [3]: '
    read -r ans </dev/tty || ans=""
    case "$ans" in 1) AGENT=claude ;; 2) AGENT=agents ;; *) AGENT=all ;; esac
  else
    AGENT=all
    say "没有交互终端，默认两个目录都装（可用 --agent claude|agents|all 指定）"
  fi
fi
case "$AGENT" in
  claude|claude-code) TARGETS="$CLAUDE_DIR" ;;
  agents|universal|codex|cursor|opencode|copilot|github-copilot) TARGETS="$AGENTS_DIR" ;;
  all|both) TARGETS="$CLAUDE_DIR $AGENTS_DIR" ;;
  *) die "--agent must be claude, agents or all (got: $AGENT)" ;;
esac

# --- tools -----------------------------------------------------------------
command -v tar >/dev/null 2>&1 || die "tar not found"
fetch() { # url dest
  if command -v curl >/dev/null 2>&1; then curl -fsSL --retry 2 --connect-timeout 15 -o "$2" "$1"
  elif command -v wget >/dev/null 2>&1; then wget -q -T 30 -O "$2" "$1"
  else die "need curl or wget"; fi
}
sha256_of() {
  if command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | awk '{print $1}'
  elif command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}'
  elif command -v openssl >/dev/null 2>&1; then openssl dgst -sha256 -r "$1" | awk '{print $1}'
  else die "need shasum, sha256sum or openssl to verify"; fi
}

TMP=$(mktemp -d 2>/dev/null || mktemp -d -t ggpr)
trap 'rm -rf "$TMP"' EXIT INT TERM

# --- download / locate -----------------------------------------------------
if [ -n "$LOCAL_FILE" ]; then
  [ -f "$LOCAL_FILE" ] || die "file not found: $LOCAL_FILE"
  cp "$LOCAL_FILE" "$TMP/$TARBALL"
  if [ -f "$LOCAL_FILE.sha256" ]; then cp "$LOCAL_FILE.sha256" "$TMP/$TARBALL.sha256"
  elif [ -z "$WANT_SHA" ]; then die "offline mode needs $LOCAL_FILE.sha256 or --sha256 <hex>"; fi
else
  say "下载 / downloading: $URL_BASE/$TARBALL"
  fetch "$URL_BASE/$TARBALL" "$TMP/$TARBALL" || die "download failed: $URL_BASE/$TARBALL"
  fetch "$URL_BASE/$TARBALL.sha256" "$TMP/$TARBALL.sha256" || die "download failed: $URL_BASE/$TARBALL.sha256"
fi

# --- verify ----------------------------------------------------------------
GOT=$(sha256_of "$TMP/$TARBALL")
if [ -f "$TMP/$TARBALL.sha256" ]; then
  PUB=$(awk 'NR==1{print tolower($1)}' "$TMP/$TARBALL.sha256")
  [ "$GOT" = "$PUB" ] || die "SHA-256 不匹配 / mismatch: got $GOT, .sha256 says $PUB"
fi
if [ -n "$WANT_SHA" ]; then
  [ "$GOT" = "$WANT_SHA" ] || die "SHA-256 不匹配 / mismatch: got $GOT, expected $WANT_SHA"
fi
say "SHA-256 校验通过 / verified: $GOT"

# --- extract safely --------------------------------------------------------
if tar tzf "$TMP/$TARBALL" | grep -Eq '^/|(^|/)\.\.(/|$)'; then die "tarball has unsafe paths, refusing"; fi
mkdir "$TMP/x"
tar xzf "$TMP/$TARBALL" -C "$TMP/x"
SRC="$TMP/x/goglobal-proxy-skill/skills/$NAME"
[ -f "$SRC/SKILL.md" ] || die "SKILL.md not found in tarball"

# --- install (an existing copy is moved to a backup, never deleted) --------
# Backups go OUTSIDE the skills dir so agents don't load two copies of the same skill.
STAMP=$(date +%Y%m%d-%H%M%S)
BACKUPS="$HOME/.config/goglobal-proxy/skill-backups"
i=0
for d in $TARGETS; do
  i=$((i+1))
  mkdir -p "$d"
  if [ -e "$d/$NAME" ]; then
    mkdir -p "$BACKUPS"; chmod 700 "$HOME/.config/goglobal-proxy" 2>/dev/null || true
    B="$BACKUPS/$NAME-$STAMP-$i"
    mv "$d/$NAME" "$B"
    say "已有旧版，已移到备份 / previous copy kept: $B"
  fi
  cp -R "$SRC" "$d/$NAME"
  say "已安装 / installed: $d/$NAME"
done

say ""
say "完成。打开你的智能体（Claude Code / Codex / Cursor …），对它说："
say "  用 goglobal-proxy-routing 这个 Skill，从 S0 开始一步一步带我配置网络"
say "Done. Tell your agent: \"Use the goglobal-proxy-routing skill and walk me through it from S0.\""
