#!/bin/bash
# ==========================================
# SSH 反向隧道启动脚本 (安全版 - 环境检查)
# 机器: JQUSFUO
# 端口: 26002
# ==========================================

SERVER="82.29.54.80"
TUNNEL_PORT=26002
LOCAL_PORT=22
LOG_FILE="$HOME/Desktop/tunnel-26002.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log_success() {
    echo -e "\033[32m[$(date '+%Y-%m-%d %H:%M:%S')] ✓ $1\033[0m" | tee -a "$LOG_FILE"
}

log_error() {
    echo -e "\033[31m[$(date '+%Y-%m-%d %H:%M:%S')] ✗ $1\033[0m" | tee -a "$LOG_FILE"
}

log_info() {
    echo -e "\033[33m[$(date '+%Y-%m-%d %H:%M:%S')] ℹ $1\033[0m" | tee -a "$LOG_FILE"
}

# 清空旧日志
> "$LOG_FILE"

log "==================================================================="
log "               环境检查与隧道启动脚本"
log "==================================================================="
log "服务器: $SERVER"
log "隧道端口: $TUNNEL_PORT"
log "本地端口: $LOCAL_PORT"
log "日志文件: $LOG_FILE"
log "==================================================================="
echo ""

# ==========================================
# 环境检查阶段
# ==========================================
log "==================================================================="
log "                    环境检查"
log "==================================================================="
echo ""

# 检查1: 操作系统
log "[环境检查 1/7] 检查操作系统..."
OS_TYPE=$(uname -s)
log_info "操作系统类型: $OS_TYPE"

if [[ "$OS_TYPE" == MINGW* ]] || [[ "$OS_TYPE" == MSYS* ]]; then
    log_success "运行在 Windows (Git Bash)"
elif [[ "$OS_TYPE" == CYGWIN* ]]; then
    log_success "运行在 Windows (Cygwin)"
else
    log_error "此脚本仅支持 Windows 系统"
    log_error "当前系统: $OS_TYPE"
    read -p "按回车键退出..."
    exit 1
fi
echo ""

# 检查2: 必要命令
log "[环境检查 2/7] 检查必要命令..."
REQUIRED_COMMANDS=("ssh" "ssh-keygen" "netstat" "ps" "powershell.exe")
ALL_COMMANDS_OK=true

for cmd in "${REQUIRED_COMMANDS[@]}"; do
    if command -v $cmd &> /dev/null; then
        log_success "$cmd: 已安装"
    else
        log_error "$cmd: 未找到"
        ALL_COMMANDS_OK=false
    fi
done

if [ "$ALL_COMMANDS_OK" = false ]; then
    log_error "缺少必要命令，无法继续"
    read -p "按回车键退出..."
    exit 1
fi
echo ""

# 检查3: SSH 客户端版本
log "[环境检查 3/7] 检查 SSH 客户端..."
SSH_VERSION=$(ssh -V 2>&1)
log_info "SSH 版本: $SSH_VERSION"
echo ""

# 检查4: PowerShell 可用性
log "[环境检查 4/7] 检查 PowerShell..."
PS_VERSION=$(powershell.exe -Command '$PSVersionTable.PSVersion.ToString()' 2>&1)
if [ $? -eq 0 ]; then
    log_success "PowerShell 可用，版本: $PS_VERSION"
else
    log_error "PowerShell 不可用"
    read -p "按回车键退出..."
    exit 1
fi
echo ""

# 检查5: 网络连接
log "[环境检查 5/7] 检查网络连接..."
log_info "测试连接到 $SERVER..."

if ping -n 2 $SERVER > /dev/null 2>&1; then
    log_success "网络连接正常 (ping $SERVER)"
else
    log_error "无法 ping 通 $SERVER"
    log_info "尝试 TCP 连接测试..."

    if timeout 5 bash -c "echo > /dev/tcp/$SERVER/22" 2>/dev/null; then
        log_success "TCP 连接正常 (端口 22)"
    else
        log_error "无法连接到 $SERVER:22"
        log_info "请检查："
        log_info "  1. 网络连接是否正常"
        log_info "  2. 防火墙是否阻止连接"
        log_info "  3. 服务器是否在线"
        read -p "是否继续？(y/n) " choice
        if [ "$choice" != "y" ] && [ "$choice" != "Y" ]; then
            exit 1
        fi
    fi
fi
echo ""

# 检查6: SSH Server 服务状态
log "[环境检查 6/7] 检查本地 SSH Server..."
log_info "查询 sshd 服务状态..."

SSHD_STATUS=$(powershell.exe -Command "Get-Service sshd -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Status" 2>&1)

if [ -z "$SSHD_STATUS" ]; then
    log_error "sshd 服务未安装"
    log_info "请先安装 OpenSSH Server"
    log_info "下载地址: https://scripts.tap365.org/OpenSSH-Win64.zip"
    read -p "按回车键退出..."
    exit 1
elif echo "$SSHD_STATUS" | grep -q "Running"; then
    log_success "SSH Server 正在运行"
elif echo "$SSHD_STATUS" | grep -q "Stopped"; then
    log_info "SSH Server 已停止，尝试启动..."
    powershell.exe -NoProfile -Command "Start-Service sshd" >> "$LOG_FILE" 2>&1
    sleep 2

    NEW_STATUS=$(powershell.exe -Command "Get-Service sshd | Select-Object -ExpandProperty Status" 2>&1)
    if echo "$NEW_STATUS" | grep -q "Running"; then
        log_success "SSH Server 启动成功"
    else
        log_error "SSH Server 启动失败"
        log_info "请在 PowerShell (管理员) 中手动执行: Start-Service sshd"
        read -p "按回车键退出..."
        exit 1
    fi
else
    log_error "无法确定 sshd 服务状态: $SSHD_STATUS"
fi
echo ""

# 检查7: 端口监听状态
log "[环境检查 7/7] 检查端口监听..."
if netstat -an | grep -q ":${LOCAL_PORT}.*LISTENING"; then
    log_success "端口 $LOCAL_PORT 正在监听"
    netstat -an | grep ":${LOCAL_PORT}.*LISTENING" | head -2 | tee -a "$LOG_FILE"
else
    log_error "端口 $LOCAL_PORT 未监听"
    log_info "SSH Server 可能未正确配置"
    read -p "是否继续？(y/n) " choice
    if [ "$choice" != "y" ] && [ "$choice" != "Y" ]; then
        exit 1
    fi
fi
echo ""

log "==================================================================="
log "                   环境检查完成"
log "==================================================================="
echo ""
sleep 2

# ==========================================
# 步骤1: 检查 SSH 密钥
# ==========================================
log "[1/7] 检查 SSH 密钥..."
if [ ! -f "$HOME/.ssh/id_rsa" ]; then
    log_info "SSH 密钥不存在，开始生成..."
    log_info "密钥路径: $HOME/.ssh/id_rsa"

    ssh-keygen -t rsa -b 4096 -f "$HOME/.ssh/id_rsa" -N "" >> "$LOG_FILE" 2>&1

    if [ $? -eq 0 ]; then
        log_success "SSH 密钥生成成功"
        log_info "公钥内容:"
        cat "$HOME/.ssh/id_rsa.pub" | tee -a "$LOG_FILE"

        log_info "需要上传公钥到服务器，请输入服务器 root 密码："
        cat "$HOME/.ssh/id_rsa.pub" | ssh root@${SERVER} "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" 2>&1 | tee -a "$LOG_FILE"

        if [ ${PIPESTATUS[1]} -eq 0 ]; then
            log_success "公钥上传成功"
        else
            log_error "公钥上传失败，请检查网络或密码"
            read -p "按回车键退出..."
            exit 1
        fi
    else
        log_error "SSH 密钥生成失败"
        read -p "按回车键退出..."
        exit 1
    fi
else
    log_success "SSH 密钥已存在: $HOME/.ssh/id_rsa"
fi
echo ""

# ==========================================
# 步骤2: 检查已有隧道进程
# ==========================================
log "[2/7] 检查已有隧道进程..."
EXISTING_PID=$(ps aux | grep -E "ssh.*-R.*${TUNNEL_PORT}:localhost:${LOCAL_PORT}" | grep -v grep | awk '{print $2}' | head -1)

if [ -n "$EXISTING_PID" ]; then
    log_info "发现已有隧道进程 (PID: $EXISTING_PID)"
    log_info "进程详情:"
    ps -p $EXISTING_PID -o pid,cmd | tee -a "$LOG_FILE"

    echo ""
    log_info "是否停止旧进程并重新启动？(y/n)"
    read -p "> " choice

    if [ "$choice" = "y" ] || [ "$choice" = "Y" ]; then
        log_info "停止进程 $EXISTING_PID..."
        kill $EXISTING_PID
        sleep 2
        log_success "旧进程已停止"
    else
        log_info "保持旧进程运行，退出脚本"
        read -p "按回车键退出..."
        exit 0
    fi
fi
echo ""

# ==========================================
# 步骤3: 测试服务器连接
# ==========================================
log "[3/7] 测试服务器 SSH 连接..."
log_info "连接到 root@$SERVER..."

ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${SERVER} "echo 'Server connection OK'" >> "$LOG_FILE" 2>&1

if [ $? -eq 0 ]; then
    log_success "服务器 SSH 连接正常"
else
    log_error "无法通过 SSH 连接到服务器 $SERVER"
    log_info "可能原因："
    log_info "  1. SSH 密钥未配置"
    log_info "  2. 服务器 SSH 服务未启动"
    log_info "  3. 防火墙阻止连接"
    read -p "按回车键退出..."
    exit 1
fi
echo ""

# ==========================================
# 步骤4: 清理服务器端僵尸端口
# ==========================================
log "[4/7] 清理服务器端可能的僵尸端口..."
log_info "检查服务器端口 $TUNNEL_PORT 状态..."

REMOTE_PORT_STATUS=$(ssh root@${SERVER} "ss -tlnp | grep :${TUNNEL_PORT}" 2>&1)
if [ -n "$REMOTE_PORT_STATUS" ]; then
    log_info "服务器端口 $TUNNEL_PORT 已被占用:"
    echo "$REMOTE_PORT_STATUS" | tee -a "$LOG_FILE"
    log_info "尝试释放端口..."
    ssh root@${SERVER} "fuser -k ${TUNNEL_PORT}/tcp 2>/dev/null" >> "$LOG_FILE" 2>&1
    sleep 2
    log_success "端口清理完成"
else
    log_success "服务器端口 $TUNNEL_PORT 空闲"
fi
echo ""

# ==========================================
# 步骤5: 启动隧道
# ==========================================
log "[5/7] 启动 SSH 反向隧道..."
log_info "执行命令:"
log_info "  ssh -N -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -R ${TUNNEL_PORT}:localhost:${LOCAL_PORT} root@${SERVER}"
echo ""

ssh -N \
    -o "ServerAliveInterval=30" \
    -o "ServerAliveCountMax=3" \
    -o "ExitOnForwardFailure=yes" \
    -o "StrictHostKeyChecking=no" \
    -R ${TUNNEL_PORT}:localhost:${LOCAL_PORT} \
    root@${SERVER} >> "$LOG_FILE" 2>&1 &

SSH_PID=$!
log_info "隧道进程已启动 (PID: $SSH_PID)"
log_info "等待隧道建立 (5秒)..."
sleep 5

# ==========================================
# 步骤6: 验证隧道进程
# ==========================================
log "[6/7] 验证隧道进程..."

if kill -0 $SSH_PID 2>/dev/null; then
    log_success "隧道进程运行正常 (PID: $SSH_PID)"
    ps -p $SSH_PID -o pid,cmd | tee -a "$LOG_FILE"
else
    log_error "隧道进程启动失败或已退出"
    log_info "请查看日志文件: $LOG_FILE"
    read -p "按回车键退出..."
    exit 1
fi
echo ""

# ==========================================
# 步骤7: 验证服务器端口监听
# ==========================================
log "[7/7] 验证服务器端口监听..."
log_info "检查服务器端口 $TUNNEL_PORT..."

sleep 2
REMOTE_LISTEN=$(ssh root@${SERVER} "ss -tlnp | grep :${TUNNEL_PORT}" 2>&1)

if [ -n "$REMOTE_LISTEN" ]; then
    log_success "服务器端口 $TUNNEL_PORT 正在监听"
    echo "$REMOTE_LISTEN" | tee -a "$LOG_FILE"
else
    log_error "服务器端口 $TUNNEL_PORT 未监听"
    log_info "隧道可能建立失败，请检查日志"
    read -p "按回车键退出..."
    exit 1
fi
echo ""

# ==========================================
# 自动测试连接
# ==========================================
log "==================================================================="
log "                      自动连接测试"
log "==================================================================="

log_info "从服务器测试回连 Windows..."
TEST_RESULT=$(ssh root@${SERVER} "timeout 10 ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no -p ${TUNNEL_PORT} Administrator@localhost 'hostname' 2>&1")

if [ $? -eq 0 ]; then
    log_success "✓✓✓ 连接测试成功！"
    log_success "返回主机名: $TEST_RESULT"
else
    log_error "连接测试失败"
    log_info "错误信息: $TEST_RESULT"
    log_info "可能原因："
    log_info "  1. Windows SSH 服务未正确配置"
    log_info "  2. 需要配置密钥认证"
    log_info "  3. 防火墙阻止连接"
fi
echo ""

# ==========================================
# 最终总结
# ==========================================
log "==================================================================="
log "                        隧道启动完成"
log "==================================================================="
log_success "隧道进程 PID: $SSH_PID"
log_success "服务器: $SERVER"
log_success "远程端口: $TUNNEL_PORT"
log_success "本地端口: $LOCAL_PORT"
log ""
log_info "Mac 连接命令:"
log_info "  ssh -p ${TUNNEL_PORT} Administrator@${SERVER}"
log ""
log_info "隧道将在后台保持运行"
log_info "关闭此窗口不影响隧道"
log ""
log_info "查看日志: cat $LOG_FILE"
log_info "停止隧道: kill $SSH_PID"
log_info "检查状态: ps -p $SSH_PID"
log "==================================================================="
echo ""

# 通知服务器写标记文件，触发自动测试
log_info "通知 Mac 端进行最终测试..."
ssh root@${SERVER} "echo '26002-ready' > /tmp/tunnel-26002-ready" 2>/dev/null

read -p "按回车键关闭此窗口..."
