#!/bin/bash
# ===================================================
# 蓝卡云维护平台 - SSLink 快速获取脚本 v3.0
# 生产级一键脚本: 登录平台 -> 搜索设备 -> 远程连接 -> 输出 SSLink
# 支持模糊搜索 + 多选交互
# 使用方法:
#   bash get_sslink.sh <设备号或关键字>
#   bash get_sslink.sh              (使用默认设备号 1603805001)
# 示例:
#   bash get_sslink.sh 1603805001
#   bash get_sslink.sh 16038        (模糊搜索，列出匹配设备供选择)
#   bash get_sslink.sh 靖江          (按名称模糊搜索)
#   bash get_sslink.sh --nonstop 1603805001  (非交互模式，直接取第一个)
# ===================================================
set -euo pipefail
IFS=$'\n\t'

# ─── 配置区 ────────────────────────────────────────
DEFAULT_DEVICE_SN="1603805001"
BASE_URL="http://web.bluecardservice.com/service"
COOKIE_FILE="/tmp/bluecard_$$.cookies"
USERNAME="lhj"
PASSWORD="1"
VERIFY="1"
REMOTE_PEOPLE="script_bot"
MAX_RETRIES=3
SLEEP_BETWEEN_RETRIES=3
CONNECT_WAIT=15
NONSTOP=false   # 非交互模式：有多个结果则自动取第一个

# ─── 颜色定义 ──────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color

# ─── 工具函数 ──────────────────────────────────────
log_info()  { echo -e "${GREEN}[INFO]${NC}  $*"; }
log_warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
log_step()  { echo -e "${CYAN}[STEP]${NC}  $*"; }
log_debug() { echo -e "${BLUE}[DEBUG]${NC} $*"; }

cleanup() {
    rm -f "$COOKIE_FILE" 2>/dev/null || true
}
trap cleanup EXIT INT TERM

# ─── 解析参数 ──────────────────────────────────────
ARGS=()
while [[ $# -gt 0 ]]; do
    case "$1" in
        --nonstop)
            NONSTOP=true
            shift
            ;;
        *)
            ARGS+=("$1")
            shift
            ;;
    esac
done

SEARCH_KEY="${ARGS[0]:-${1:-$DEFAULT_DEVICE_SN}}"

# ─── 打印头部 ─────────────────────────────────────
echo ""
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
echo -e "${CYAN}   蓝卡云维护平台 · SSLink 获取工具 v3.0${NC}"
echo -e "${CYAN}   搜索关键字: ${SEARCH_KEY}${NC}"
echo -e "${CYAN}   时间:       $(date '+%Y-%m-%d %H:%M:%S')${NC}"
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
echo ""

# ═══════════════════════════════════════════════════
# STEP 1: 登录
# ═══════════════════════════════════════════════════
log_step "1/4: 登录平台..."

LOGIN_RESP=""
for ((i=1; i<=MAX_RETRIES; i++)); do
    LOGIN_RESP=$(curl -s -c "$COOKIE_FILE" \
        -X POST "$BASE_URL/login2.do" \
        -d "username=${USERNAME}&password1=${PASSWORD}&verify=${VERIFY}" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        --connect-timeout 10 \
        --max-time 15 \
        2>/dev/null || true)

    # 检查是否获取到 cookie（JSESSIONID）
    if [[ -f "$COOKIE_FILE" ]] && grep -q "JSESSIONID" "$COOKIE_FILE" 2>/dev/null; then
        # 验证登录状态
        LOGIN_STATUS=$(echo "$LOGIN_RESP" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    print(data.get('status', 'fail'))
except:
    print('fail')
" 2>/dev/null)

        if [[ "$LOGIN_STATUS" == "success" ]]; then
            log_info "登录成功 ✅"
            break
        fi
    fi

    if [[ $i -lt MAX_RETRIES ]]; then
        log_warn "登录失败 (尝试 $i/$MAX_RETRIES)，${SLEEP_BETWEEN_RETRIES}秒后重试..."
        sleep "$SLEEP_BETWEEN_RETRIES"
    else
        log_error "登录失败，已达最大重试次数 ($MAX_RETRIES)"
        log_error "响应原文: $LOGIN_RESP"
        exit 1
    fi
done

echo ""

# ═══════════════════════════════════════════════════
# STEP 2: 搜索设备（支持模糊搜索）
# ═══════════════════════════════════════════════════
log_step "2/4: 搜索设备 \"${SEARCH_KEY}\"..."

# 先访问 devices.jsp 以建立会话上下文
curl -s -b "$COOKIE_FILE" \
    -X GET "$BASE_URL/device/devices.jsp" \
    --connect-timeout 10 \
    --max-time 15 \
    -o /dev/null \
    2>/dev/null || true

DEVICE_JSON=$(curl -s -b "$COOKIE_FILE" \
    -X POST "$BASE_URL/device/pageLoad?deviceSnAll=${SEARCH_KEY}&deviceNameAll=-1&deviceStateAll=-1&page=1&rows=50" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "X-Requested-With: XMLHttpRequest" \
    --connect-timeout 10 \
    --max-time 15 \
    2>/dev/null || true)

if [[ -z "$DEVICE_JSON" ]]; then
    log_error "搜索设备时网络请求失败，请检查网络连接"
    exit 1
fi

# 解析所有匹配的设备列表
DEVICE_LIST=$(echo "$DEVICE_JSON" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    rows = data.get('rows', [])
    if not rows:
        print('NOT_FOUND')
        sys.exit(0)
    results = []
    for row in rows:
        results.append({
            'id': row.get('id', ''),
            'device_sn': row.get('device_sn', ''),
            'name': row.get('name', ''),
            'state': row.get('state', 0),
            'remote': row.get('remote', 0),
            'port8080': row.get('port8080', 0),
            'device_ip': row.get('device_ip', ''),
            'mac': row.get('mac', ''),
            'operator_name': row.get('operator_name', ''),
        })
    print(json.dumps(results))
except Exception as e:
    print(f'PARSE_ERROR: {e}')
" 2>/dev/null)

if [[ "$DEVICE_LIST" == "NOT_FOUND" ]]; then
    log_error "未找到匹配 '${SEARCH_KEY}' 的设备"
    echo "  可能原因: 设备号/名称输入错误，或设备尚未注册到平台"
    echo "  提示: 可以尝试更短的关键字进行模糊搜索"
    exit 1
fi

if [[ "$DEVICE_LIST" == PARSE_ERROR:* ]]; then
    log_error "解析设备数据失败"
    log_error "原始响应前200字符: ${DEVICE_JSON:0:200}"
    exit 1
fi

# 计算匹配数量
MATCH_COUNT=$(echo "$DEVICE_LIST" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null)
echo ""
log_info "找到 ${MATCH_COUNT} 个匹配设备:"
echo ""

# ─── 显示设备列表 ────────────────────────────────
echo -e "${CYAN}  ┌────┬──────────────────┬──────────────────────────────────┬────────┬──────────┬─────────────┐${NC}"
echo -e "${CYAN}  │ #  │ 设备号            │ 名称                             │ 状态   │ 远程     │ IP          │${NC}"
echo -e "${CYAN}  ├────┼──────────────────┼──────────────────────────────────┼────────┼──────────┼─────────────┤${NC}"

# 保存每行摘要到临时数组（通过文件传递）
TMP_ITEMS=$(mktemp)
echo "$DEVICE_LIST" | python3 -c "
import sys, json, re
data = json.load(sys.stdin)

# 去除 ANSI 颜色的正则
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\\[[0-?]*[ -/]*[@-~])')

for idx, row in enumerate(data):
    sn = row.get('device_sn', '')
    name = row.get('name', '')
    state = row.get('state', 0)
    remote = row.get('remote', 0)
    ip = row.get('device_ip', '')
    oper = row.get('operator_name', '')
    
    state_str = '在线' if state == 1 else '离线'
    
    if remote == 1:
        remote_str = '已远程'
        if oper:
            remote_str += f'({oper})'
    else:
        remote_str = '未远程'
    
    print(f'{idx+1}|{sn}|{name}|{state_str}|{remote_str}|{ip}')
" 2>/dev/null > "$TMP_ITEMS"

# 读取并格式化显示
ITEMS=()
while IFS= read -r line; do
    [[ -z "$line" ]] && continue
    ITEMS+=("$line")
    IFS='|' read -r num sn name state remote ip <<< "$line"
    printf "  │ ${GREEN}%-2s${NC} │ ${YELLOW}%-16s${NC} │ %-32s │ %-6s │ %-8s │ %-11s │\n" \
        "$num" "$sn" "${name:0:32}" "$state" "$remote" "$ip"
done < "$TMP_ITEMS"

echo -e "${CYAN}  └────┴──────────────────┴──────────────────────────────────┴────────┴──────────┴─────────────┘${NC}"
echo ""

# ─── 选择设备 ──────────────────────────────────────
SELECTED_INDEX=0

if [[ "$MATCH_COUNT" -eq 1 ]]; then
    SELECTED_INDEX=1
    log_info "仅匹配到一个设备，自动选择 #1"
elif [[ "$NONSTOP" == true ]]; then
    SELECTED_INDEX=1
    log_info "非交互模式(--nonstop)，自动选择第一个设备 #1"
else
    echo -e "${MAGENTA}  ⚡ 请输入序号选择设备 (1-${MATCH_COUNT})，直接回车默认选 #1:${NC} "
    read -r USER_CHOICE
    
    if [[ -z "$USER_CHOICE" ]]; then
        SELECTED_INDEX=1
        log_info "未输入，默认选择 #1"
    elif [[ "$USER_CHOICE" =~ ^[0-9]+$ ]] && [[ "$USER_CHOICE" -ge 1 ]] && [[ "$USER_CHOICE" -le "$MATCH_COUNT" ]]; then
        SELECTED_INDEX="$USER_CHOICE"
    else
        log_error "无效选择: '$USER_CHOICE'，请输入 1-${MATCH_COUNT} 之间的数字"
        rm -f "$TMP_ITEMS"
        exit 1
    fi
fi

# 获取选中的设备行
SELECTED_LINE="${ITEMS[$((SELECTED_INDEX-1))]}"
IFS='|' read -r _ DEV_SN DEV_NAME DEV_STATE_TEXT DEV_REMOTE_TEXT DEV_IP <<< "$SELECTED_LINE"

rm -f "$TMP_ITEMS"

echo ""

# ─── 获取选中设备的详细信息 ─────────────────────────
# 重新查询精确设备号以获取完整字段
DEVICE_JSON=$(curl -s -b "$COOKIE_FILE" \
    -X POST "$BASE_URL/device/pageLoad?deviceSnAll=${DEV_SN}&deviceNameAll=-1&deviceStateAll=-1&page=1&rows=10" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "X-Requested-With: XMLHttpRequest" \
    --connect-timeout 10 \
    --max-time 15 \
    2>/dev/null || true)

DEVICE_INFO=$(echo "$DEVICE_JSON" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    rows = data.get('rows', [])
    if not rows:
        print('NOT_FOUND')
        sys.exit(0)
    row = rows[0]
    out = {
        'id': row.get('id', ''),
        'device_sn': row.get('device_sn', ''),
        'name': row.get('name', ''),
        'state': row.get('state', 0),
        'remote': row.get('remote', 0),
        'port8080': row.get('port8080', 0),
        'port23': row.get('port23', 0),
        'device_ip': row.get('device_ip', ''),
        'mac': row.get('mac', ''),
        'operator_name': row.get('operator_name', ''),
    }
    print(json.dumps(out))
except Exception as e:
    print(f'PARSE_ERROR: {e}')
" 2>/dev/null)

# 提取字段
DEV_SN=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['device_sn'])")
DEV_NAME=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin).get('name',''))")
DEV_STATE=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['state'])")
DEV_REMOTE=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['remote'])")
DEV_PORT=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin)['port8080'])")
DEV_IP=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin).get('device_ip',''))")
DEV_OPER=$(echo "$DEVICE_INFO" | python3 -c "import sys,json; print(json.load(sys.stdin).get('operator_name',''))")

# 格式化显示状态
if [[ "$DEV_STATE" == "1" ]]; then
    STATE_STR="${GREEN}在线${NC}"
else
    STATE_STR="${RED}离线${NC}"
fi

if [[ "$DEV_REMOTE" == "1" ]]; then
    REMOTE_STR="${GREEN}已远程${NC}"
    [[ -n "$DEV_OPER" ]] && REMOTE_STR="${REMOTE_STR} (操作人: $DEV_OPER)"
else
    REMOTE_STR="${YELLOW}未远程${NC}"
fi

echo ""
log_info "选中设备信息:"
echo -e "  ┌──────────────────────────────────────────────┐"
echo -e "  │ 设备号:     ${DEV_SN}"
echo -e "  │ 名称:       ${DEV_NAME}"
echo -e "  │ 状态:       ${STATE_STR}"
echo -e "  │ 远程状态:   ${REMOTE_STR}"
echo -e "  │ 设备IP:     ${DEV_IP}"
echo -e "  │ 代理端口:   ${DEV_PORT}"
echo -e "  └──────────────────────────────────────────────┘"
echo ""

# ═══════════════════════════════════════════════════
# STEP 3: 获取服务器地址
# ═══════════════════════════════════════════════════
log_step "3/4: 获取服务器地址..."

SERVER_ADDR=$(curl -s -b "$COOKIE_FILE" \
    -X POST "$BASE_URL/device/getConfig" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --connect-timeout 10 \
    --max-time 15 \
    2>/dev/null || true)

# getConfig 返回纯文本 IP（不是 JSON）
if [[ -z "$SERVER_ADDR" ]]; then
    log_error "获取服务器地址失败"
    exit 1
fi

# 简单的 IP 地址格式验证
if ! [[ "$SERVER_ADDR" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    log_warn "服务器地址格式异常: '$SERVER_ADDR' (可能不是标准IP地址)"
fi

log_info "服务器地址: ${GREEN}${SERVER_ADDR}${NC}"
echo ""

# ═══════════════════════════════════════════════════
# STEP 4: 远程连接
# ═══════════════════════════════════════════════════
log_step "4/4: 检查/建立远程连接..."

# 检查设备是否离线
if [[ "$DEV_STATE" != "1" ]]; then
    log_warn "设备状态为离线，无法建立远程连接"
    echo ""
    echo -e "  ${YELLOW}提示: 请确认设备已通电并联网后再试${NC}"
    echo ""
    exit 1
fi

NEED_CONNECT=false
if [[ "$DEV_REMOTE" != "1" ]]; then
    NEED_CONNECT=true
elif [[ "$DEV_PORT" == "0" ]] || [[ -z "$DEV_PORT" ]]; then
    log_warn "设备标记为已远程但端口为0，尝试重新连接..."
    NEED_CONNECT=true
fi

if [[ "$NEED_CONNECT" == true ]]; then
    log_info "设备未远程，发起远程连接请求..."
    
    CONNECT_RESP=""
    for ((i=1; i<=MAX_RETRIES; i++)); do
        CONNECT_RESP=$(curl -s -b "$COOKIE_FILE" \
            -X POST "$BASE_URL/device/deviceLink" \
            -d "deviceSn=${DEV_SN}&remote_people=${REMOTE_PEOPLE}" \
            -H "Content-Type: application/x-www-form-urlencoded" \
            -H "X-Requested-With: XMLHttpRequest" \
            --connect-timeout 10 \
            --max-time 15 \
            2>/dev/null || true)

        CONN_STATE=$(echo "$CONNECT_RESP" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    print(data.get('state', 'fail'))
except:
    print('parse_error')
" 2>/dev/null)

        if [[ "$CONN_STATE" == "success" ]]; then
            log_info "远程连接请求已发送，等待 ${CONNECT_WAIT} 秒建立连接..."
            
            # 轮询等待连接建立
            for ((w=1; w<=CONNECT_WAIT; w++)); do
                sleep 1
                # 重新查询设备状态
                POLL_JSON=$(curl -s -b "$COOKIE_FILE" \
                    -X POST "$BASE_URL/device/pageLoad?deviceSnAll=${DEV_SN}&deviceNameAll=-1&deviceStateAll=-1&page=1&rows=10" \
                    -H "Content-Type: application/x-www-form-urlencoded" \
                    -H "X-Requested-With: XMLHttpRequest" \
                    --connect-timeout 5 \
                    --max-time 8 \
                    2>/dev/null || true)
                
                POLL_PORT=$(echo "$POLL_JSON" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    rows = data.get('rows', [])
    if rows:
        print(rows[0].get('port8080', 0))
    else:
        print(0)
except:
    print(0)
" 2>/dev/null)

                POLL_REMOTE=$(echo "$POLL_JSON" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    rows = data.get('rows', [])
    if rows:
        print(rows[0].get('remote', 0))
    else:
        print(0)
except:
    print(0)
" 2>/dev/null)

                if [[ "$POLL_REMOTE" == "1" ]] && [[ "$POLL_PORT" != "0" ]] && [[ -n "$POLL_PORT" ]]; then
                    DEV_PORT="$POLL_PORT"
                    DEV_REMOTE="1"
                    log_info "连接已建立 ✅ (端口: ${DEV_PORT})"
                    break 2  # break out of both loops
                fi
                
                if [[ $w -lt CONNECT_WAIT ]]; then
                    echo -ne "  ${YELLOW}等待连接... (${w}/${CONNECT_WAIT}s)${NC}\r"
                else
                    echo -ne "\r"
                    log_warn "连接等待超时 (${CONNECT_WAIT}s)，部分设备需要更长时间"
                    if [[ -n "$POLL_PORT" ]] && [[ "$POLL_PORT" != "0" ]]; then
                        DEV_PORT="$POLL_PORT"
                    fi
                fi
            done
            break
        elif [[ $i -lt MAX_RETRIES ]]; then
            log_warn "远程连接请求失败 (尝试 $i/$MAX_RETRIES)，${SLEEP_BETWEEN_RETRIES}秒后重试..."
            sleep "$SLEEP_BETWEEN_RETRIES"
        else
            log_error "远程连接请求失败，已达最大重试次数"
            log_error "响应: $CONNECT_RESP"
            exit 1
        fi
    done
else
    log_info "设备已处于远程连接状态 ✅"
    if [[ -n "$DEV_OPER" ]]; then
        log_info "当前操作人: ${DEV_OPER}"
    fi
fi

echo ""

# ═══════════════════════════════════════════════════
# 输出 SSLink
# ═══════════════════════════════════════════════════
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
echo -e "${CYAN}   🔗 SSLink 连接串${NC}"
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
echo ""

# 最终检查端口
if [[ -z "$DEV_PORT" || "$DEV_PORT" == "0" ]]; then
    log_warn "端口为 0，连接可能尚未完全建立"
    log_info "可稍后使用以下参数手动连接:"
    echo ""
    echo "  sslink:SocksCap64 -i${SERVER_ADDR} -p<待获取端口> -t6 -u -s123456 -cchacha20-ietf-poly1305 --quit"
    echo ""
    log_info "或重新运行本脚本以获取最新状态"
    exit 1
fi

SSLINK="sslink:SocksCap64 -i${SERVER_ADDR} -p${DEV_PORT} -t6 -u -s123456 -cchacha20-ietf-poly1305 --quit"

echo -e "  ${GREEN}${SSLINK}${NC}"
echo ""
echo -e "  参数详情:"
echo -e "  ┌────────────────────────────────────────────────────┐"
echo -e "  │  协议:      SocksCap64"
echo -e "  │  地址:      ${SERVER_ADDR}"
echo -e "  │  端口:      ${DEV_PORT}"
echo -e "  │  密码:      123456"
echo -e "  │  加密:      chacha20-ietf-poly1305"
echo -e "  │  设备号:    ${DEV_SN}"
echo -e "  │  设备名称:  ${DEV_NAME}"
echo -e "  └────────────────────────────────────────────────────┘"
echo ""

# 提供一键复制提示 (macOS / Linux 兼容)
if command -v pbcopy &>/dev/null; then
    echo "$SSLINK" | pbcopy 2>/dev/null && log_info "SSLink 已复制到剪贴板 📋"
elif command -v xclip &>/dev/null; then
    echo "$SSLINK" | xclip -selection clipboard 2>/dev/null && log_info "SSLink 已复制到剪贴板 📋"
elif command -v wl-copy &>/dev/null; then
    echo "$SSLINK" | wl-copy 2>/dev/null && log_info "SSLink 已复制到剪贴板 📋"
fi

log_info "操作完成 ✅"
echo ""
