#!/bin/bash

# Node.js 服务管理脚本 - 宁夏智慧养殖监管平台后端
# 使用方法: ./node_manager.sh [start|stop|restart|status]

# 配置区域
APP_NAME="nxxmdata-backend"
ENTRY_FILE="server.js"
APP_PORT="5350"
LOG_DIR="logs"
LOG_FILE="${LOG_DIR}/${APP_NAME}.log"
PID_FILE="pid.${APP_NAME}"
NODE_ENV="production"

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

# 创建日志目录
if [ ! -d "$LOG_DIR" ]; then
    mkdir -p "$LOG_DIR"
    echo "已创建日志目录: $LOG_DIR"
fi

# 检查 Node.js 是否安装
if ! command -v node &> /dev/null; then
    echo -e "${RED}错误: Node.js 未安装或不在 PATH 中${NC}"
    exit 1
fi

# 检查入口文件是否存在
if [ ! -f "$ENTRY_FILE" ]; then
    echo -e "${RED}错误: 入口文件 $ENTRY_FILE 不存在${NC}"
    exit 1
fi

# 显示 Node.js 版本信息
NODE_VERSION=$(node --version)
echo -e "${GREEN}Node.js 版本: $NODE_VERSION${NC}"

# 停止服务函数
function stopApp() {
    echo -e "${YELLOW}正在停止服务: $APP_NAME${NC}"
    
    # 从 PID 文件读取进程 ID
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p $PID > /dev/null 2>&1; then
            echo "找到进程 PID: $PID，正在停止..."
            kill -TERM $PID
            
            # 等待进程优雅退出
            for i in {1..10}; do
                if ! ps -p $PID > /dev/null 2>&1; then
                    echo -e "${GREEN}服务已优雅停止${NC}"
                    rm -f "$PID_FILE"
                    return 0
                fi
                sleep 1
            done
            
            # 如果优雅停止失败，强制杀死
            echo -e "${YELLOW}优雅停止失败，强制终止进程${NC}"
            kill -9 $PID
            rm -f "$PID_FILE"
        else
            echo "PID 文件存在但进程不存在，清理 PID 文件"
            rm -f "$PID_FILE"
        fi
    else
        # 如果没有 PID 文件，尝试通过端口查找
        PID=$(lsof -ti:$APP_PORT 2>/dev/null)
        if [ -n "$PID" ]; then
            echo "通过端口 $APP_PORT 找到 PID: $PID，正在停止..."
            kill -TERM $PID
            sleep 2
            if ps -p $PID > /dev/null 2>&1; then
                kill -9 $PID
            fi
            echo -e "${GREEN}服务已停止${NC}"
        else
            echo -e "${YELLOW}未找到运行中的服务: $APP_NAME${NC}"
        fi
    fi
}

# 启动服务函数
function startApp() {
    echo -e "${YELLOW}正在启动服务: $APP_NAME${NC}"
    
    # 检查服务是否已经运行
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p $PID > /dev/null 2>&1; then
            echo -e "${YELLOW}服务已在运行中 (PID: $PID)${NC}"
            return 0
        else
            echo "PID 文件存在但进程不存在，清理后重新启动"
            rm -f "$PID_FILE"
        fi
    fi
    
    # 检查端口是否被占用
    if command -v lsof &> /dev/null; then
        PORT_CHECK=$(lsof -ti:$APP_PORT 2>/dev/null)
        if [ -n "$PORT_CHECK" ]; then
            echo -e "${RED}错误: 端口 $APP_PORT 已被占用 (PID: $PORT_CHECK)${NC}"
            echo "请先停止占用端口的进程或使用 restart 命令"
            return 1
        fi
    fi
    
    # 检查 .env 文件是否存在
    if [ ! -f ".env" ]; then
        echo -e "${YELLOW}警告: .env 文件不存在，将使用默认配置${NC}"
        echo "建议从 env.example 复制并配置 .env 文件"
    fi
    
    # 检查 node_modules 是否存在
    if [ ! -d "node_modules" ]; then
        echo -e "${RED}错误: node_modules 目录不存在${NC}"
        echo "请先运行: npm install"
        return 1
    fi
    
    # 启动 Node.js 应用
    echo "启动命令: NODE_ENV=$NODE_ENV nohup node $ENTRY_FILE > $LOG_FILE 2>&1 &"
    NODE_ENV=$NODE_ENV nohup node $ENTRY_FILE > $LOG_FILE 2>&1 &
    
    # 获取新进程的 PID
    PID=$!
    echo $PID > "$PID_FILE"
    
    # 等待应用启动
    echo "等待服务启动..."
    sleep 3
    
    # 验证启动是否成功
    if ps -p $PID > /dev/null 2>&1; then
        echo -e "${GREEN}========================================${NC}"
        echo -e "${GREEN}服务启动成功!${NC}"
        echo -e "${GREEN}========================================${NC}"
        echo "应用名称: $APP_NAME"
        echo "进程 ID:  $PID"
        echo "监听端口: $APP_PORT"
        echo "日志文件: $LOG_FILE"
        echo "PID 文件: $PID_FILE"
        echo "环境变量: NODE_ENV=$NODE_ENV"
        echo -e "${GREEN}API 文档: http://localhost:$APP_PORT/api-docs${NC}"
        echo ""
        
        # 等待端口监听
        echo "检查端口监听状态..."
        sleep 2
        if command -v lsof &> /dev/null; then
            if lsof -ti:$APP_PORT > /dev/null 2>&1; then
                echo -e "${GREEN}✓ 端口 $APP_PORT 正在监听${NC}"
            else
                echo -e "${YELLOW}⚠ 端口 $APP_PORT 尚未监听，请检查日志${NC}"
            fi
        fi
        
        # 显示最近的日志
        echo ""
        echo "最近的启动日志:"
        echo "------------------------"
        tail -20 "$LOG_FILE"
    else
        echo -e "${RED}========================================${NC}"
        echo -e "${RED}服务启动失败!${NC}"
        echo -e "${RED}========================================${NC}"
        echo "请检查日志文件: $LOG_FILE"
        echo ""
        echo "最近的错误日志:"
        echo "------------------------"
        tail -30 "$LOG_FILE"
        rm -f "$PID_FILE"
        exit 1
    fi
}

# 重启服务函数
function restartApp() {
    echo -e "${YELLOW}正在重启服务: $APP_NAME${NC}"
    stopApp
    sleep 3
    startApp
}

# 状态检查函数
function statusApp() {
    echo -e "${YELLOW}检查服务状态: $APP_NAME${NC}"
    echo "========================================"
    
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p $PID > /dev/null 2>&1; then
            echo -e "${GREEN}✓ 服务正在运行${NC}"
            echo "----------------------------------------"
            echo "进程 ID:    $PID"
            echo "应用名称:   $APP_NAME"
            echo "监听端口:   $APP_PORT"
            
            # 启动时间
            if command -v ps &> /dev/null; then
                START_TIME=$(ps -o lstart= -p $PID 2>/dev/null)
                if [ -n "$START_TIME" ]; then
                    echo "启动时间:   $START_TIME"
                fi
                
                # 内存使用
                MEM_USAGE=$(ps -o rss= -p $PID 2>/dev/null | awk '{printf "%.2f MB", $1/1024}')
                if [ -n "$MEM_USAGE" ]; then
                    echo "内存使用:   $MEM_USAGE"
                fi
                
                # CPU使用率
                CPU_USAGE=$(ps -o %cpu= -p $PID 2>/dev/null)
                if [ -n "$CPU_USAGE" ]; then
                    echo "CPU 使用:   ${CPU_USAGE}%"
                fi
            fi
            
            # 检查端口监听状态
            if command -v lsof &> /dev/null; then
                PORT_INFO=$(lsof -ti:$APP_PORT 2>/dev/null)
                if [ -n "$PORT_INFO" ]; then
                    echo -e "端口状态:   ${GREEN}监听中 ($APP_PORT)${NC}"
                else
                    echo -e "端口状态:   ${RED}未监听${NC}"
                fi
            fi
            
            # 日志文件信息
            if [ -f "$LOG_FILE" ]; then
                LOG_SIZE=$(du -h "$LOG_FILE" | cut -f1)
                echo "日志大小:   $LOG_SIZE"
                echo "日志文件:   $LOG_FILE"
            fi
            
            echo ""
            echo "最近的日志 (最后10行):"
            echo "----------------------------------------"
            tail -10 "$LOG_FILE" 2>/dev/null || echo "无法读取日志文件"
            
        else
            echo -e "${RED}✗ 服务未运行 (PID 文件存在但进程不存在)${NC}"
            echo "建议清理 PID 文件: rm -f $PID_FILE"
        fi
    else
        # 通过端口检查
        if command -v lsof &> /dev/null; then
            PID=$(lsof -ti:$APP_PORT 2>/dev/null)
            if [ -n "$PID" ]; then
                echo -e "${YELLOW}⚠ 服务正在运行但未通过脚本管理${NC}"
                echo "进程 ID:    $PID"
                echo "监听端口:   $APP_PORT"
                echo "建议使用: ./node_manager.sh stop 停止服务后重新启动"
            else
                echo -e "${RED}✗ 服务未运行${NC}"
                echo "使用以下命令启动: ./node_manager.sh start"
            fi
        else
            echo -e "${RED}✗ 服务未运行 (PID 文件不存在)${NC}"
            echo "使用以下命令启动: ./node_manager.sh start"
        fi
    fi
    echo "========================================"
}

# 查看日志函数
function viewLogs() {
    if [ -f "$LOG_FILE" ]; then
        echo -e "${YELLOW}实时查看日志 (Ctrl+C 退出):${NC}"
        tail -f "$LOG_FILE"
    else
        echo -e "${RED}日志文件不存在: $LOG_FILE${NC}"
    fi
}

# 主逻辑
case "$1" in
    start)
        startApp
        ;;
    stop)
        stopApp
        ;;
    restart)
        restartApp
        ;;
    status)
        statusApp
        ;;
    logs)
        viewLogs
        ;;
    *)
        echo "========================================"
        echo "宁夏智慧养殖监管平台 - 服务管理脚本"
        echo "========================================"
        echo "使用方法: $0 {start|stop|restart|status|logs}"
        echo ""
        echo "命令说明:"
        echo "  start   - 启动服务"
        echo "  stop    - 停止服务"
        echo "  restart - 重启服务"
        echo "  status  - 查看服务状态"
        echo "  logs    - 实时查看日志"
        echo ""
        echo "配置信息:"
        echo "  应用名称: $APP_NAME"
        echo "  入口文件: $ENTRY_FILE"
        echo "  监听端口: $APP_PORT"
        echo "  日志文件: $LOG_FILE"
        echo ""
        echo "示例:"
        echo "  $0 start    # 启动服务"
        echo "  $0 status   # 查看状态"
        echo "  $0 logs     # 查看日志"
        exit 1
        ;;
esac

exit 0

