#!/bin/bash
################################################################################
# 51_service_check.sh — 平台服务检测
# 功能: 检测核心业务服务进程状态(auth/gateway/system/meeting/mqtt/quartz/message/extapi)
#       + upython/upython_voice 容器端口监听
# 参考: ServiceCheck.psm1, check_server_health.sh
# 日期: 2026-07-22
# 说明: 服务进程检测优先用 ps grep 匹配 jar 文件名；端口检测用进程检查代替 ss
#       （避免容器内无 ss/netstat 导致误判，详见 HANDOFF 坑 9）
################################################################################

# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"

# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
    source "$LIB_DIR/lib/config.sh"
else
    echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
    exit 1
fi

if [ -f "$LIB_DIR/lib/common.sh" ]; then
    source "$LIB_DIR/lib/common.sh"
else
    echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
    exit 1
fi

# 服务匹配模式（从 config.sh 读取或使用默认值，格式: key:pattern,key:pattern）
UJAVA_SERVICES="${UJAVA_SERVICES:-auth:ubains-auth.jar,gateway:ubains-gateway.jar,system:ubains-modules-system.jar,meeting:ubains-meeting-inner-api-1.0-SNAPSHOT.jar,mqtt:ubains-meeting-mqtt-1.0-SNAPSHOT.jar,quartz:ubains-meeting-quartz-1.0-SNAPSHOT.jar,message:ubains-meeting-message-scheduling-1.0-SNAPSHOT.jar}"
UJAVA_HOST_SERVICES="${UJAVA_HOST_SERVICES:-extapi:ubains-meeting-api-1.0-SNAPSHOT.jar}"
UJAVA_OLD_CONTAINER_SERVICES="${UJAVA_OLD_CONTAINER_SERVICES:-nginx:nginx: master process,meeting:ubains-meeting-inner-api-1.0-SNAPSHOT.jar}"
UJAVA_OLD_HOST_SERVICES="${UJAVA_OLD_HOST_SERVICES:-extapi:ubains-meeting-api-1.0-SNAPSHOT.jar}"

# 端口列表（格式: port:process,port:process）
UPYTHON_PORTS_NEW="${UPYTHON_PORTS_NEW:-8000:uwsgi,11211:memcached}"
UPYTHON_VOICE_PORTS_NEW="${UPYTHON_VOICE_PORTS_NEW:-8000:uwsgi,11211:memcached,8080:nginx,1883:mosquitto,9001:mosquitto}"
UPYTHON_PORTS_OLD="${UPYTHON_PORTS_OLD:-8000:uwsgi,11211:memcached,8081:nginx,8443:nginx,8002:httpd}"

# 将服务名转为大写用于 KEY（兼容 bash 3.x macOS / bash 4+ 都用 tr）
to_upper() {
    echo "$1" | tr '[:lower:]' '[:upper:]'
}

# ==================== 平台/容器类型识别（内部实现，不依赖 50 模块） ====================

detect_platform_type() {
    [ -d "/data/services" ] && echo "new" || echo "old"
}

detect_container_type() {
    local containers
    containers=$(docker ps --format '{{.Names}}' 2>/dev/null)
    if echo "$containers" | grep -qE '^ujava[0-9]*$'; then
        echo "ujava"
    elif echo "$containers" | grep -qE '^upython_voice[0-9]*$'; then
        echo "upython_voice"
    elif echo "$containers" | grep -qE '^upython[0-9]*$'; then
        echo "upython"
    else
        echo "unknown"
    fi
}

# ==================== 服务进程检测 ====================

# 检测容器内服务进程
# 参数: container pattern key_prefix
check_service_in_container() {
    local container="$1"
    local pattern="$2"
    local key_prefix="$3"

    if [ -z "$container" ]; then
        output_result "${key_prefix}_STATUS" "未检测到容器"
        output_result "${key_prefix}_STATUS_LEVEL" "跳过"
        return
    fi

    local count
    count=$(docker exec "$container" ps aux 2>/dev/null | grep -F "$pattern" | grep -v grep | wc -l)

    if [ "$count" -gt 0 ]; then
        output_result "${key_prefix}_STATUS" "运行中"
        output_result "${key_prefix}_STATUS_LEVEL" "正常"
    else
        output_result "${key_prefix}_STATUS" "未运行"
        output_result "${key_prefix}_STATUS_LEVEL" "严重"
    fi
}

# 检测宿主机服务进程
# 参数: pattern key_prefix [path_hint]
check_service_on_host() {
    local pattern="$1"
    local key_prefix="$2"
    local path_hint="$3"

    local count
    if [ -n "$path_hint" ]; then
        count=$(ps aux 2>/dev/null | grep -F "$pattern" | grep -F "$path_hint" | grep -v grep | wc -l)
    else
        count=$(ps aux 2>/dev/null | grep -F "$pattern" | grep -v grep | wc -l)
    fi

    if [ "$count" -gt 0 ]; then
        output_result "${key_prefix}_STATUS" "运行中"
        output_result "${key_prefix}_STATUS_LEVEL" "正常"
    else
        output_result "${key_prefix}_STATUS" "未运行"
        output_result "${key_prefix}_STATUS_LEVEL" "严重"
    fi
}

# ==================== 端口监听检测（用进程检查代替 ss） ====================

# 检测容器内端口对应的进程
# 参数: container port process
check_port_in_container() {
    local container="$1"
    local port="$2"
    local process="$3"
    local key_prefix="SVC_CHECK_PORT_${port}"

    if [ -z "$container" ]; then
        output_result "${key_prefix}_STATUS" "未检测到容器"
        output_result "${key_prefix}_STATUS_LEVEL" "跳过"
        return
    fi

    local count
    count=$(docker exec "$container" ps aux 2>/dev/null | grep "$process" | grep -v grep | wc -l)

    if [ "$count" -gt 0 ]; then
        output_result "${key_prefix}_STATUS" "监听"
        output_result "${key_prefix}_STATUS_LEVEL" "正常"
    else
        output_result "${key_prefix}_STATUS" "未监听"
        output_result "${key_prefix}_STATUS_LEVEL" "严重"
    fi
}

# ==================== 服务列表遍历辅助 ====================

# 遍历 "key:pattern,key:pattern" 字符串，对每个服务在容器内检测
# 参数: services_str container key_suffix
check_services_in_container_list() {
    local services_str="$1"
    local container="$2"
    local key_suffix="$3"

    local IFS_save="$IFS"
    IFS=','
    local services=($services_str)
    IFS="$IFS_save"

    for svc in "${services[@]}"; do
        [ -z "$svc" ] && continue
        local key pattern
        key="${svc%%:*}"
        pattern="${svc#*:}"
        [ -z "$key" ] || [ -z "$pattern" ] && continue
        check_service_in_container "$container" "$pattern" "SVC_CHECK_$(to_upper "$key")${key_suffix}"
    done
}

# 遍历 "key:pattern,..." 字符串，对每个服务在宿主机检测
# 参数: services_str key_suffix [path_hint]
check_services_on_host_list() {
    local services_str="$1"
    local key_suffix="$2"
    local path_hint="$3"

    local IFS_save="$IFS"
    IFS=','
    local services=($services_str)
    IFS="$IFS_save"

    for svc in "${services[@]}"; do
        [ -z "$svc" ] && continue
        local key pattern
        key="${svc%%:*}"
        pattern="${svc#*:}"
        [ -z "$key" ] || [ -z "$pattern" ] && continue
        if [ -n "$path_hint" ]; then
            check_service_on_host "$pattern" "SVC_CHECK_$(to_upper "$key")${key_suffix}" "$path_hint"
        else
            check_service_on_host "$pattern" "SVC_CHECK_$(to_upper "$key")${key_suffix}"
        fi
    done
}

# 遍历 "port:process,..." 字符串，对每个端口在容器内检测
# 参数: ports_str container
check_ports_in_container_list() {
    local ports_str="$1"
    local container="$2"

    local IFS_save="$IFS"
    IFS=','
    local ports=($ports_str)
    IFS="$IFS_save"

    for pp in "${ports[@]}"; do
        [ -z "$pp" ] && continue
        local port process
        port="${pp%%:*}"
        process="${pp#*:}"
        [ -z "$port" ] || [ -z "$process" ] && continue
        check_port_in_container "$container" "$port" "$process"
    done
}

# ==================== 主检测流程 ====================

main() {
    log_info "开始平台服务检测..."

    set +e

    local platform_type container_type
    platform_type=$(detect_platform_type)
    container_type=$(detect_container_type)

    # 获取容器名
    local ujava_container upython_container
    ujava_container=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -E '^ujava[0-9]*$' | head -1)
    upython_container=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -E '^upython' | head -1)

    if [ "$platform_type" = "new" ]; then
        # 新平台：ujava 容器内服务
        if [ "$container_type" = "ujava" ]; then
            check_services_in_container_list "$UJAVA_SERVICES" "$ujava_container" ""
        fi

        # 新平台：宿主机 extapi
        check_services_on_host_list "$UJAVA_HOST_SERVICES" ""

        # 新平台：upython/upython_voice 端口
        if [ "$container_type" = "upython" ]; then
            check_ports_in_container_list "$UPYTHON_PORTS_NEW" "$upython_container"
        elif [ "$container_type" = "upython_voice" ]; then
            check_ports_in_container_list "$UPYTHON_VOICE_PORTS_NEW" "$upython_container"
        fi
    else
        # 传统平台：ujava 容器内服务（nginx + meeting）
        if [ "$container_type" = "ujava" ]; then
            check_services_in_container_list "$UJAVA_OLD_CONTAINER_SERVICES" "$ujava_container" "_OLD"
        fi

        # 传统平台：宿主机 extapi（匹配路径）
        check_services_on_host_list "$UJAVA_OLD_HOST_SERVICES" "_OLD" "/var/www/java/external-meeting-api"

        # 传统平台：upython 端口
        if [ "$container_type" = "upython" ] || [ "$container_type" = "upython_voice" ]; then
            check_ports_in_container_list "$UPYTHON_PORTS_OLD" "$upython_container"
        fi
    fi

    log_info "平台服务检测完成"
}

main
