#!/bin/bash

# ============================================
# 灵越智报 - 同步代码并部署脚本
# 从本地同步代码到服务器并重启应用
# ============================================

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# ========== 配置区域 ==========
# 服务器配置（根据实际情况修改）
SERVER_USER="root"
SERVER_HOST="${SERVER_HOST:-lanaipc}"  # 可通过环境变量覆盖，或直接改为 IP
SERVER_PORT="${SERVER_PORT:-22}"

# 路径配置
LOCAL_PROJECT_DIR="/home/hws/workspace/GitLab/ay/lingyue-zhibao"
REMOTE_PROJECT_DIR="/mnt/win_home/lingyue-zhibao"
REMOTE_MAVEN_REPO="/mnt/win_home/.m2/repository"

# 应用配置
APP_PORT=5232
JAR_NAME="lingyue-starter.jar"
# ==============================

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_title() { echo -e "\n${BLUE}========== $1 ==========${NC}\n"; }

# SSH 命令封装
ssh_cmd() {
    ssh -p ${SERVER_PORT} ${SERVER_USER}@${SERVER_HOST} "$@"
}

# 检查服务器连接
check_connection() {
    log_title "检查服务器连接"
    
    if ssh_cmd "echo 'OK'" > /dev/null 2>&1; then
        log_info "服务器连接成功: ${SERVER_USER}@${SERVER_HOST}"
    else
        log_error "无法连接服务器: ${SERVER_USER}@${SERVER_HOST}"
        log_warn "请检查："
        log_warn "  1. 服务器地址是否正确"
        log_warn "  2. SSH 密钥是否配置"
        log_warn "  3. 可以通过 SERVER_HOST=<IP> ./sync-and-deploy.sh 指定服务器"
        exit 1
    fi
}

# 同步代码
sync_code() {
    log_title "同步代码到服务器"
    
    cd ${LOCAL_PROJECT_DIR}
    
    log_info "正在同步..."
    rsync -avz --delete \
        --exclude '.git' \
        --exclude 'target' \
        --exclude 'node_modules' \
        --exclude '.idea' \
        --exclude '*.iml' \
        --exclude '.DS_Store' \
        --exclude 'frontend_flutter/build' \
        --exclude 'frontend_flutter/.dart_tool' \
        -e "ssh -p ${SERVER_PORT}" \
        ./ ${SERVER_USER}@${SERVER_HOST}:${REMOTE_PROJECT_DIR}/
    
    log_info "代码同步完成"
}

# 停止应用
stop_app() {
    log_title "停止应用"
    
    ssh_cmd "pkill -f '${JAR_NAME}' 2>/dev/null || true"
    sleep 2
    
    # 确保进程已停止
    if ssh_cmd "pgrep -f '${JAR_NAME}'" > /dev/null 2>&1; then
        log_warn "进程仍在运行，强制终止..."
        ssh_cmd "pkill -9 -f '${JAR_NAME}' 2>/dev/null || true"
        sleep 2
    fi
    
    log_info "应用已停止"
}

# 编译项目
build_project() {
    log_title "编译项目"
    
    ssh_cmd "cd ${REMOTE_PROJECT_DIR}/backend && \
             rm -rf lingyue-starter/target && \
             mvn clean package -DskipTests -q -Dmaven.repo.local=${REMOTE_MAVEN_REPO}"
    
    log_info "编译完成"
}

# 启动应用
start_app() {
    log_title "启动应用"
    
    ssh_cmd "cd ${REMOTE_PROJECT_DIR}/backend && \
             nohup java -Xms1g -Xmx2g -XX:+UseG1GC \
                   -jar lingyue-starter/target/${JAR_NAME} \
                   > /var/log/lingyue.log 2>&1 &"
    
    log_info "应用启动中..."
    sleep 5
    
    # 检查应用是否启动
    if ssh_cmd "pgrep -f '${JAR_NAME}'" > /dev/null 2>&1; then
        log_info "应用启动成功"
    else
        log_error "应用启动失败，查看日志："
        ssh_cmd "tail -50 /var/log/lingyue.log"
        exit 1
    fi
}

# 健康检查
health_check() {
    log_title "健康检查"
    
    local max_attempts=10
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        log_info "尝试 $attempt/$max_attempts..."
        
        local response=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://localhost:${APP_PORT}/actuator/health 2>/dev/null" || echo "000")
        
        if [ "$response" = "200" ]; then
            log_info "健康检查通过 ✓"
            ssh_cmd "curl -s http://localhost:${APP_PORT}/actuator/health"
            echo ""
            return 0
        fi
        
        sleep 3
        attempt=$((attempt + 1))
    done
    
    log_warn "健康检查超时，但应用可能仍在启动中"
    log_info "可以手动检查: curl http://${SERVER_HOST}:${APP_PORT}/actuator/health"
}

# 查看日志
show_logs() {
    log_title "应用日志"
    ssh_cmd "tail -100 /var/log/lingyue.log"
}

# 查看实时日志
tail_logs() {
    log_info "实时日志 (Ctrl+C 退出)"
    ssh_cmd "tail -f /var/log/lingyue.log"
}

# 查看状态
show_status() {
    log_title "应用状态"
    
    if ssh_cmd "pgrep -f '${JAR_NAME}'" > /dev/null 2>&1; then
        local pid=$(ssh_cmd "pgrep -f '${JAR_NAME}'")
        log_info "应用运行中 (PID: $pid)"
        log_info "访问地址: http://${SERVER_HOST}:${APP_PORT}"
    else
        log_warn "应用未运行"
    fi
}

# 仅同步代码（不编译不重启）
sync_only() {
    check_connection
    sync_code
    log_info "代码同步完成，未编译和重启"
}

# 完整部署
full_deploy() {
    check_connection
    sync_code
    stop_app
    build_project
    start_app
    health_check
    
    log_title "部署完成"
    echo -e "${GREEN}访问地址: http://${SERVER_HOST}:${APP_PORT}${NC}"
    echo ""
    echo "测试命令："
    echo "  curl http://${SERVER_HOST}:${APP_PORT}/actuator/health"
    echo "  curl -X POST http://${SERVER_HOST}:${APP_PORT}/auth/register -H 'Content-Type: application/json' -d '{\"username\":\"test\",\"email\":\"test@test.com\",\"password\":\"123456\"}'"
}

# 快速重启（不同步代码）
quick_restart() {
    check_connection
    stop_app
    start_app
    health_check
}

# 显示帮助
show_help() {
    cat <<EOF
灵越智报 - 同步代码并部署脚本

用法: ./sync-and-deploy.sh [命令]

命令:
    deploy          完整部署（同步 + 编译 + 重启）
    sync            仅同步代码（不编译不重启）
    restart         快速重启（不同步代码）
    stop            停止应用
    status          查看应用状态
    logs            查看最近日志
    tail            实时查看日志
    build           远程编译（不重启）
    help            显示此帮助

环境变量:
    SERVER_HOST     服务器地址（默认: lanaipc）
    SERVER_PORT     SSH 端口（默认: 22）

示例:
    ./sync-and-deploy.sh deploy                    # 完整部署
    ./sync-and-deploy.sh sync                      # 仅同步
    ./sync-and-deploy.sh restart                   # 快速重启
    SERVER_HOST=192.168.1.100 ./sync-and-deploy.sh deploy  # 指定服务器

EOF
}

# 主函数
main() {
    case "${1:-deploy}" in
        deploy)
            full_deploy
            ;;
        sync)
            sync_only
            ;;
        restart)
            quick_restart
            ;;
        stop)
            check_connection
            stop_app
            ;;
        status)
            check_connection
            show_status
            ;;
        logs)
            check_connection
            show_logs
            ;;
        tail)
            check_connection
            tail_logs
            ;;
        build)
            check_connection
            build_project
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            log_error "未知命令: $1"
            show_help
            exit 1
            ;;
    esac
}

main "$@"
