#!/bin/bash
# 交互式把本节点注册到 api 后台（装机的最后一步）。
#
# 流程：① 输入管理员账号密码 → ② 选择节点组 → ③ 输入节点名称和连接(套餐)数量 → 自动注册。
# 注册参数：host={public_ip}:{AGENT_API_PORT}（nginx 反代到本机 agent 契约口），
#           api_key/proxy_path/info_proxy_path 取自 node.env（deploy-agent.sh 生成的随机值）。
# 默认「关闭大陆IP出口」(allow_cn_ip=false)；可在后台节点管理页随时切换。
#
# 前置：setup-node.sh + deploy-agent.sh 已跑完（node.env 含 PUBLIC_IP/API_KEY/PROXY_PATH/INFO_PROXY_PATH，agent 在跑）。
# 非交互/自动化：可用环境变量预置任意输入，跳过对应提示：
#   API_BASE ADMIN_USER ADMIN_PASS GROUP_ID NODE_NAME MAX_PACKAGES ALLOW_CN_IP
set -o pipefail

API_BASE="${API_BASE:-https://api.guayangtou.top}"
AGENT_API_PORT="${AGENT_API_PORT:-10443}"
NODE_ENV="${NODE_ENV:-/etc/node-agent/node.env}"
AGENT_CFG="${AGENT_CFG:-/etc/node-agent/config.yaml}"

# 读取本节点契约参数（环境变量优先，其次 node.env）
[ -f "$NODE_ENV" ] && source "$NODE_ENV"
PUBLIC_IP="${PUBLIC_IP:-}"
API_KEY="${API_KEY:-}"
PROXY_PATH="${PROXY_PATH:-}"
INFO_PROXY_PATH="${INFO_PROXY_PATH:-}"
NODE_HOST="${NODE_HOST:-${PUBLIC_IP}:${AGENT_API_PORT}}"
if [ -z "$PUBLIC_IP" ] || [ -z "$API_KEY" ] || [ -z "$PROXY_PATH" ] || [ -z "$INFO_PROXY_PATH" ]; then
  echo "ERROR: 缺少节点契约参数（PUBLIC_IP/API_KEY/PROXY_PATH/INFO_PROXY_PATH）。请先跑 setup-node.sh + deploy-agent.sh。"
  exit 1
fi

echo "=== 注册节点到 api 后台：$API_BASE ==="
echo "本节点 host = $NODE_HOST"
echo

# ① 管理员账号密码
ADMIN_USER="${ADMIN_USER:-}"
ADMIN_PASS="${ADMIN_PASS:-}"
[ -z "$ADMIN_USER" ] && read -rp "① 管理员账号: " ADMIN_USER </dev/tty
[ -z "$ADMIN_PASS" ] && { read -rsp "① 管理员密码: " ADMIN_PASS </dev/tty; echo; }
LOGIN=$(curl -s --max-time 20 -X POST "$API_BASE/api/auth/admin/login" \
  -H 'Content-Type: application/json' \
  -d "{\"username\":\"${ADMIN_USER}\",\"password\":\"${ADMIN_PASS}\"}")
TOKEN=$(echo "$LOGIN" | grep -oE '"token":"[^"]*"' | head -1 | sed 's/.*"token":"//;s/"$//')
[ -z "$TOKEN" ] && { echo "ERROR: 登录失败：$LOGIN"; exit 1; }
echo "  ✓ 登录成功"
echo

# ② 选择节点组（动态拉取列表→编号选择；零依赖纯 shell 解析，拉取失败再回退手动输 ID）
GROUP_ID="${GROUP_ID:-}"
if [ -z "$GROUP_ID" ]; then
  GRESP=$(curl -s -w $'\n%{http_code}' --max-time 20 "$API_BASE/api/admin/node-groups?page=1&pageSize=1000" -H "Authorization: Bearer $TOKEN")
  GCODE=$(printf '%s' "$GRESP" | tail -n1)
  GBODY=$(printf '%s' "$GRESP" | sed '$d')
  # 把 data.list 的每个对象拆成一行，逐行 awk-match 抽 "序号<tab>id<tab>名称<tab>可用余量<tab>节点数"。
  # 纯 awk/sed/grep，不依赖 python3/jq（节点上可能缺解释器，这是上次只能手动输 ID 的根因）。
  LIST=$(printf '%s' "$GBODY" | sed 's/},{/}\n{/g' | grep '"id":' | awk '
    {
      id=""; name=""; nc=""; av="";
      if (match($0, /"id":[0-9]+/))                id=substr($0,RSTART+5,RLENGTH-5);
      if (match($0, /"name":"[^"]*"/))             name=substr($0,RSTART+8,RLENGTH-9);
      if (match($0, /"nodeCount":[0-9]+/))         nc=substr($0,RSTART+12,RLENGTH-12);
      if (match($0, /"availableCapacity":[0-9]+/)) av=substr($0,RSTART+20,RLENGTH-20);
      if (id!="") printf "%d\t%s\t%s\t%s\t%s\n", ++n, id, name, av, nc;
    }')
  if [ -n "$LIST" ]; then
    echo "② 可选节点组（共 $(printf '%s\n' "$LIST" | grep -c .) 个）："
    printf '%s\n' "$LIST" | awk -F'\t' '{printf "  %3d) [id=%s] %s  (可用 %s / 节点 %s)\n", $1, $2, $3, $4, $5}'
    read -rp "   选择节点组序号: " IDX </dev/tty
    GROUP_ID=$(printf '%s\n' "$LIST" | awk -F'\t' -v n="$IDX" '$1==n{print $2}')
    [ -z "$GROUP_ID" ] && { echo "ERROR: 序号「$IDX」无对应节点组"; exit 1; }
  else
    echo "② ⚠ 无法自动列出节点组（HTTP ${GCODE}，响应：$(printf '%s' "$GBODY" | head -c 300)）"
    echo "   请在后台「节点管理 → 节点组」里查到目标组的 ID，手动输入："
    read -rp "   节点组 ID: " GROUP_ID </dev/tty
  fi
  [ -z "$GROUP_ID" ] && { echo "ERROR: 未确定节点组"; exit 1; }
fi
echo "  ✓ 节点组 id=$GROUP_ID"
echo

# ③ 节点名称 + 连接(套餐)数量
NODE_NAME="${NODE_NAME:-}"
MAX_PACKAGES="${MAX_PACKAGES:-}"
[ -z "$NODE_NAME" ] && read -rp "③ 节点名称: " NODE_NAME </dev/tty
[ -z "$MAX_PACKAGES" ] && read -rp "③ 最大连接(套餐)数量: " MAX_PACKAGES </dev/tty
ALLOW_CN_IP="${ALLOW_CN_IP:-false}"   # 默认关闭大陆IP出口
case "$MAX_PACKAGES" in ''|*[!0-9]*) echo "ERROR: 连接数量必须是正整数"; exit 1;; esac

# ④ 注册
REG=$(curl -s --max-time 30 -X POST "$API_BASE/api/admin/nodes" -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"groupId\":${GROUP_ID},\"name\":\"${NODE_NAME}\",\"host\":\"${NODE_HOST}\",\"apiKey\":\"${API_KEY}\",\"proxyPath\":\"${PROXY_PATH}\",\"infoProxyPath\":\"${INFO_PROXY_PATH}\",\"maxPackages\":${MAX_PACKAGES},\"allowCnIp\":${ALLOW_CN_IP}}")
if echo "$REG" | grep -q '"code":200'; then
  echo "✓ 注册成功：「${NODE_NAME}」 host=${NODE_HOST} → 节点组 ${GROUP_ID}，最大连接 ${MAX_PACKAGES}，大陆IP出口=$([ "$ALLOW_CN_IP" = true ] && echo 允许 || echo 禁止)"
  # 同步 agent 链接标签为该节点名称
  if [ -f "$AGENT_CFG" ]; then
    sed -i "s/^  name: .*/  name: \"${NODE_NAME}\"/" "$AGENT_CFG"
    systemctl restart node-agent 2>/dev/null || true
  fi
else
  echo "ERROR: 注册失败：$REG"; exit 1
fi
