#!/bin/bash
# ================================================
# Urban Lifeline - 服务管理脚本
# 
# 用法:
#   ./service-manager.sh start-all          # 启动所有服务
#   ./service-manager.sh start gateway      # 启动单个服务
#   ./service-manager.sh stop gateway       # 停止单个服务
#   ./service-manager.sh restart gateway    # 重启单个服务
#   ./service-manager.sh status             # 查看所有服务状态
#   ./service-manager.sh logs gateway       # 查看服务日志
# ================================================

set -e

# 目录配置
JAR_DIR="/app/jars"
LOG_DIR="/app/logs"
PID_DIR="/app/pids"
CONFIG_DIR="/app/config"

# 服务配置: 服务名=端口:内存
declare -A SERVICES=(
    ["gateway"]="8080:384m"
    ["system"]="8082:384m"
    ["auth"]="8081:256m"
    ["file"]="8084:256m"
    # ["log"]="8083:192m"
    # ["message"]="8085:256m"
    # ["crontab"]="8086:192m"
    ["ai"]="8090:384m"
    # ["bidding"]="8087:256m"
    # ["platform"]="8089:256m"
    ["workcase"]="8088:384m"
)

# 启动顺序 (有依赖关系)
# BOOT_ORDER=(gateway system auth file log message crontab ai bidding platform workcase)
BOOT_ORDER=(gateway system auth file ai workcase)

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

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

# 获取服务端口
get_port() {
    local service=$1
    echo "${SERVICES[$service]}" | cut -d: -f1
}

# 获取服务内存配置
get_memory() {
    local service=$1
    echo "${SERVICES[$service]}" | cut -d: -f2
}

# 检查服务是否运行
is_running() {
    local service=$1
    local pid_file="${PID_DIR}/${service}.pid"
    
    if [ -f "$pid_file" ]; then
        local pid=$(cat "$pid_file")
        if kill -0 "$pid" 2>/dev/null; then
            return 0
        fi
    fi
    return 1
}

# 等待服务就绪
wait_for_service() {
    local service=$1
    local port=$(get_port "$service")
    local max_wait=60
    local count=0
    
    while [ $count -lt $max_wait ]; do
        if curl -sf "http://localhost:${port}/actuator/health" > /dev/null 2>&1; then
            return 0
        fi
        sleep 2
        count=$((count + 2))
    done
    return 1
}

# 启动单个服务
start_service() {
    local service=$1
    local port=$(get_port "$service")
    local memory=$(get_memory "$service")
    local jar_file="${JAR_DIR}/${service}.jar"
    local log_file="${LOG_DIR}/${service}.log"
    local pid_file="${PID_DIR}/${service}.pid"
    local bootstrap_file="${CONFIG_DIR}/bootstrap.yml"
    local app_config_file="${CONFIG_DIR}/application-${service}.yml"
    
    if [ ! -f "$jar_file" ]; then
        log_error "JAR 文件不存在: $jar_file"
        return 1
    fi
    
    if is_running "$service"; then
        log_warn "$service 已在运行 (PID: $(cat $pid_file))"
        return 0
    fi
    
    log_info "启动 $service (端口: $port, 内存: $memory)..."
    
    # JVM 参数
    local java_opts="-Xms128m -Xmx${memory} -XX:+UseG1GC -XX:MaxGCPauseMillis=100"
    java_opts="$java_opts -Djava.security.egd=file:/dev/./urandom"
    java_opts="$java_opts -Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-prod}"
    
    # Nacos 配置
    if [ -n "$NACOS_SERVER_ADDR" ]; then
        java_opts="$java_opts -Dspring.cloud.nacos.discovery.server-addr=$NACOS_SERVER_ADDR"
        java_opts="$java_opts -Dspring.cloud.nacos.config.server-addr=$NACOS_SERVER_ADDR"
    fi
    
    if [ -n "$NACOS_NAMESPACE" ]; then
        java_opts="$java_opts -Dspring.cloud.nacos.discovery.namespace=$NACOS_NAMESPACE"
        java_opts="$java_opts -Dspring.cloud.nacos.config.namespace=$NACOS_NAMESPACE"
    fi
    
    # 外挂配置文件: bootstrap.yml + application-{service}.yml
    local config_locations=""
    if [ -f "$bootstrap_file" ]; then
        config_locations="file:${bootstrap_file}"
        log_info "  加载通用配置: ${bootstrap_file}"
    fi
    if [ -f "$app_config_file" ]; then
        if [ -n "$config_locations" ]; then
            config_locations="${config_locations},file:${app_config_file}"
        else
            config_locations="file:${app_config_file}"
        fi
        log_info "  加载服务配置: ${app_config_file}"
    fi
    if [ -n "$config_locations" ]; then
        java_opts="$java_opts -Dspring.config.additional-location=${config_locations}"
    fi
    
    # 启动服务
    nohup java $java_opts -jar "$jar_file" > "$log_file" 2>&1 &
    local pid=$!
    echo $pid > "$pid_file"
    
    log_info "$service 已启动 (PID: $pid)"
}

# 停止单个服务
stop_service() {
    local service=$1
    local pid_file="${PID_DIR}/${service}.pid"
    
    if ! is_running "$service"; then
        log_warn "$service 未在运行"
        return 0
    fi
    
    local pid=$(cat "$pid_file")
    log_info "停止 $service (PID: $pid)..."
    
    # 优雅关闭
    kill -15 "$pid" 2>/dev/null || true
    
    # 等待进程退出
    local count=0
    while [ $count -lt 30 ] && kill -0 "$pid" 2>/dev/null; do
        sleep 1
        count=$((count + 1))
    done
    
    # 强制关闭
    if kill -0 "$pid" 2>/dev/null; then
        log_warn "强制终止 $service..."
        kill -9 "$pid" 2>/dev/null || true
    fi
    
    rm -f "$pid_file"
    log_info "$service 已停止"
}

# 重启单个服务
restart_service() {
    local service=$1
    stop_service "$service"
    sleep 2
    start_service "$service"
}

# 启动所有服务
start_all() {
    log_info "=========================================="
    log_info "  Urban Lifeline - 启动所有服务"
    log_info "=========================================="
    
    # 等待 Nacos
    if [ -n "$NACOS_SERVER_ADDR" ]; then
        log_info "等待 Nacos 就绪..."
        local nacos_host=$(echo $NACOS_SERVER_ADDR | cut -d: -f1)
        local nacos_port=$(echo $NACOS_SERVER_ADDR | cut -d: -f2)
        
        for i in $(seq 1 30); do
            if curl -sf "http://${nacos_host}:${nacos_port}/nacos/" > /dev/null 2>&1; then
                log_info "Nacos 已就绪"
                break
            fi
            sleep 2
        done
    fi
    
    # 按顺序启动服务，等待健康检查通过后再启动下一个
    for service in "${BOOT_ORDER[@]}"; do
        start_service "$service"
        
        log_info "等待 $service 健康检查..."
        if wait_for_service "$service"; then
            log_info "$service 已就绪 ✓"
        else
            log_warn "$service 健康检查超时，继续启动下一个服务"
        fi
    done
    
    log_info "=========================================="
    log_info "  所有服务启动完成"
    log_info "=========================================="
    
    show_status
    
    # 保持容器运行并监控
    monitor_services
}

# 停止所有服务
stop_all() {
    log_info "停止所有服务..."
    
    # 逆序停止
    for ((i=${#BOOT_ORDER[@]}-1; i>=0; i--)); do
        stop_service "${BOOT_ORDER[$i]}"
    done
    
    log_info "所有服务已停止"
}

# 查看服务状态
show_status() {
    echo ""
    echo "=========================================="
    echo "  Urban Lifeline 服务状态"
    echo "=========================================="
    printf "%-12s %-8s %-8s %-10s\n" "服务" "端口" "PID" "状态"
    echo "------------------------------------------"
    
    for service in "${BOOT_ORDER[@]}"; do
        local port=$(get_port "$service")
        local pid_file="${PID_DIR}/${service}.pid"
        local pid="-"
        local status="${RED}停止${NC}"
        
        if [ -f "$pid_file" ]; then
            pid=$(cat "$pid_file")
            if kill -0 "$pid" 2>/dev/null; then
                status="${GREEN}运行中${NC}"
            fi
        fi
        
        printf "%-12s %-8s %-8s " "$service" "$port" "$pid"
        echo -e "$status"
    done
    echo "=========================================="
}

# 查看服务日志
show_logs() {
    local service=$1
    local log_file="${LOG_DIR}/${service}.log"
    
    if [ ! -f "$log_file" ]; then
        log_error "日志文件不存在: $log_file"
        return 1
    fi
    
    tail -f "$log_file"
}

# 监控服务 (保持容器运行)
monitor_services() {
    log_info "进入监控模式..."
    
    # 捕获退出信号
    trap 'stop_all; exit 0' SIGTERM SIGINT
    
    while true; do
        sleep 30
        
        # 检查服务状态，自动重启挂掉的服务
        for service in "${BOOT_ORDER[@]}"; do
            if ! is_running "$service"; then
                log_warn "$service 已停止，尝试重启..."
                start_service "$service"
            fi
        done
    done
}

# 主入口
case "${1:-help}" in
    start-all)
        start_all
        ;;
    stop-all)
        stop_all
        ;;
    start)
        if [ -z "$2" ]; then
            log_error "请指定服务名"
            exit 1
        fi
        start_service "$2"
        ;;
    stop)
        if [ -z "$2" ]; then
            log_error "请指定服务名"
            exit 1
        fi
        stop_service "$2"
        ;;
    restart)
        if [ -z "$2" ]; then
            log_error "请指定服务名"
            exit 1
        fi
        restart_service "$2"
        ;;
    status)
        show_status
        ;;
    logs)
        if [ -z "$2" ]; then
            log_error "请指定服务名"
            exit 1
        fi
        show_logs "$2"
        ;;
    *)
        echo "Urban Lifeline 服务管理"
        echo ""
        echo "用法: $0 <命令> [服务名]"
        echo ""
        echo "命令:"
        echo "  start-all          启动所有服务"
        echo "  stop-all           停止所有服务"
        echo "  start <服务>       启动指定服务"
        echo "  stop <服务>        停止指定服务"
        echo "  restart <服务>     重启指定服务"
        echo "  status             查看服务状态"
        echo "  logs <服务>        查看服务日志"
        echo ""
        echo "可用服务: ${!SERVICES[*]}"
        ;;
esac
