#!/bin/bash

# 情绪博物馆后端服务远程部署脚本
# 在远程服务器上执行的服务部署脚本

set -e

# 配置变量
APP_NAME="emotion-museum-single"
JAR_NAME="emotion-single-1.0.0.jar"
DEPLOY_DIR="/data/programs/emotion-museum"
LOG_DIR="/data/logs/emotion-museum"
JAR_PATH="$DEPLOY_DIR/$JAR_NAME"
PID_FILE="/tmp/${APP_NAME}.pid"
JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_DIR}/heapdump.hprof"

# 获取 Spring Profile 参数
SPRING_PROFILE=${1:-test}

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查 jar 文件是否存在
check_jar() {
    if [ ! -f "$JAR_PATH" ]; then
        log_error "JAR 文件不存在: $JAR_PATH"
        exit 1
    fi
    log_info "JAR 文件检查通过: $JAR_PATH"
}

# 停止旧服务
stop_service() {
    # 1. 尝试通过 PID 文件停止
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null 2>&1; then
            log_info "停止旧服务 (PID: $PID)"
            kill "$PID"
            
            # 等待服务停止
            for i in {1..30}; do
                if ! ps -p "$PID" > /dev/null 2>&1; then
                    log_info "服务已停止"
                    break
                fi
                sleep 1
            done
            
            # 强制停止
            if ps -p "$PID" > /dev/null 2>&1; then
                log_warn "强制停止服务 (PID: $PID)"
                kill -9 "$PID"
            fi
        else
            log_warn "PID 文件存在但进程不存在，清理 PID 文件"
        fi
        rm -f "$PID_FILE"
    fi

    # 2. 双重检查：通过进程名查找并停止（防止 PID 文件丢失的情况）
    PIDS=$(ps aux | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
    if [ -n "$PIDS" ]; then
        log_warn "检测到残留进程 (PIDs: $PIDS)，正在清理..."
        for PID in $PIDS; do
            log_info "停止残留进程 $PID"
            kill "$PID" 2>/dev/null || true
        done
        
        sleep 5
        
        # 再次检查并强制停止
        PIDS=$(ps aux | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
        if [ -n "$PIDS" ]; then
            for PID in $PIDS; do
                log_warn "强制停止残留进程 $PID"
                kill -9 "$PID" 2>/dev/null || true
            done
        fi
    fi
}

# 启动新服务
start_service() {
    log_info "启动新服务..."
    
    # 检查JAR文件
    check_jar
    
    # 启动命令
    nohup java $JAVA_OPTS \
        -Dspring.profiles.active=$SPRING_PROFILE \
        -Dlogging.file.path=$LOG_DIR \
        -Dlogging.file.name=$LOG_DIR/emotion-single.log \
        -jar "$JAR_PATH" \
        > "$LOG_DIR/startup.log" 2>&1 &
    
    # 保存 PID
    echo $! > "$PID_FILE"
    
    log_info "服务启动中，PID: $(cat $PID_FILE)"
    log_info "启动日志: $LOG_DIR/startup.log"
    log_info "应用日志: $LOG_DIR/emotion-single.log"
}

# 检查服务状态
check_status() {
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null 2>&1; then
            log_info "服务运行中 (PID: $PID)"
            return 0
        else
            log_error "PID 文件存在但进程不存在"
            return 1
        fi
    else
        log_error "PID 文件不存在，服务未运行"
        return 1
    fi
}

# 等待服务启动
wait_for_startup() {
    log_info "等待服务启动..."
    for i in {1..60}; do
        if check_status > /dev/null 2>&1; then
            # 检查端口是否监听（使用 19089 端口）
            if netstat -tlnp 2>/dev/null | grep -q ":19089.*LISTEN"; then
                log_info "服务启动成功！"
                return 0
            fi
        fi
        sleep 2
    done
    
    log_error "服务启动超时，请检查日志: $LOG_DIR/startup.log"
    return 1
}

# 显示服务信息
show_info() {
    log_info "=== 服务信息 ==="
    log_info "应用名称: $APP_NAME"
    log_info "JAR 文件: $JAR_PATH"
    log_info "部署目录: $DEPLOY_DIR"
    log_info "日志目录: $LOG_DIR"
    log_info "PID 文件: $PID_FILE"
    log_info "Java 参数: $JAVA_OPTS"
    log_info "Spring Profile: $SPRING_PROFILE"
    
    if check_status > /dev/null 2>&1; then
        PID=$(cat "$PID_FILE")
        log_info "服务状态: 运行中 (PID: $PID)"
    else
        log_info "服务状态: 未运行"
    fi
}

# 主函数
main() {
    log_info "开始在服务器上部署 $APP_NAME 服务..."
    
    # 创建日志目录
    log_info "创建日志目录: $LOG_DIR"
    mkdir -p "$LOG_DIR"
    
    # 停止旧服务
    stop_service
    
    # 启动新服务
    start_service
    
    # 等待启动
    if wait_for_startup; then
        log_info "服务器部署成功！"
        show_info
    else
        log_error "服务器部署失败！"
        exit 1
    fi
}

# 执行主函数
main