#!/bin/bash
################################################################################
# 综合诊断检测模块
# 功能: 汇总所有检测异常，进行核心问题诊断和历史对比分析
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################

# 获取脚本所在目录并加载依赖
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

# ==================== 检测函数 ====================

# 诊断系统负载
diagnose_system_load() {
    local load1
    load1=$(cat /proc/loadavg 2>/dev/null | awk '{print $1}')

    if [ -n "$load1" ]; then
        local cpu_count
        cpu_count=$(nproc 2>/dev/null || echo "1")
        local load_per_cpu
        load_per_cpu=$(awk "BEGIN {printf \"%.2f\", $load1 / $cpu_count}")

        output_result "DIAG_LOAD_1MIN" "$load1"
        output_result "DIAG_LOAD_PER_CPU" "$load_per_cpu"

        local level="正常"
        if [ $(awk "BEGIN {print ($load_per_cpu > 4)}") -eq 1 ]; then
            level="严重"
        elif [ $(awk "BEGIN {print ($load_per_cpu > 2)}") -eq 1 ]; then
            level="警告"
        fi
        output_result "DIAG_LOAD_LEVEL" "$level"
    fi
}

# 诊断内存压力
diagnose_memory_pressure() {
    local mem_info
    mem_info=$(free -m 2>/dev/null | grep "Mem:")

    if [ -n "$mem_info" ]; then
        local total used free
        total=$(echo "$mem_info" | awk '{print $2}')
        used=$(echo "$mem_info" | awk '{print $3}')
        free=$(echo "$mem_info" | awk '{print $4}')

        local mem_usage
        mem_usage=$(awk "BEGIN {printf \"%.1f\", ($used / $total) * 100}")

        output_result "DIAG_MEMORY_USAGE" "${mem_usage}%"
        output_result "DIAG_MEMORY_TOTAL" "${total}MB"
        output_result "DIAG_MEMORY_USED" "${used}MB"
        output_result "DIAG_MEMORY_FREE" "${free}MB"

        local level="正常"
        if [ $(awk "BEGIN {print ($mem_usage > 95)}") -eq 1 ]; then
            level="严重"
        elif [ $(awk "BEGIN {print ($mem_usage > 85)}") -eq 1 ]; then
            level="警告"
        fi
        output_result "DIAG_MEMORY_LEVEL" "$level"
    fi
}

# 诊断磁盘使用
diagnose_disk_usage() {
    local disk_info
    disk_info=$(df -h / 2>/dev/null | tail -1)

    if [ -n "$disk_info" ]; then
        local usage
        usage=$(echo "$disk_info" | awk '{print $5}' | tr -d '%')

        output_result "DIAG_DISK_USAGE" "${usage}%"

        local level="正常"
        if [ "$usage" -gt 95 ]; then
            level="严重"
        elif [ "$usage" -gt 85 ]; then
            level="警告"
        fi
        output_result "DIAG_DISK_LEVEL" "$level"
    fi
}

# 诊断Docker容器状态
diagnose_docker_status() {
    if ! command -v docker &>/dev/null; then
        return
    fi

    local total running stopped
    total=$(docker ps -a --format "{{.Names}}" 2>/dev/null | wc -l)
    running=$(docker ps --format "{{.Names}}" 2>/dev/null | wc -l)
    stopped=$((total - running))

    output_result "DIAG_DOCKER_TOTAL" "$total"
    output_result "DIAG_DOCKER_RUNNING" "$running"
    output_result "DIAG_DOCKER_STOPPED" "$stopped"

    if [ "$stopped" -gt 5 ]; then
        output_result "DIAG_DOCKER_LEVEL" "警告"
    else
        output_result "DIAG_DOCKER_LEVEL" "正常"
    fi
}

# 诊断系统稳定性
diagnose_system_stability() {
    local issues=0

    # 检查OOM
    if command -v dmesg &>/dev/null; then
        local oom_count
        oom_count=$(dmesg 2>/dev/null | grep -ci "out of memory" || echo "0")
        if [ "$oom_count" -gt 0 ]; then
            issues=$((issues + oom_count))
            output_result "DIAG_OOM_ISSUES" "$oom_count"
        fi
    fi

    # 检查磁盘错误
    if command -v dmesg &>/dev/null; then
        local disk_errors
        disk_errors=$(dmesg 2>/dev/null | grep -ciE "I/O error|disk error" || echo "0")
        if [ "$disk_errors" -gt 0 ]; then
            issues=$((issues + disk_errors))
            output_result "DIAG_DISK_ISSUES" "$disk_errors"
        fi
    fi

    output_result "DIAG_TOTAL_ISSUES" "$issues"

    if [ "$issues" -gt 10 ]; then
        output_result "DIAG_STABILITY_LEVEL" "严重"
    elif [ "$issues" -gt 0 ]; then
        output_result "DIAG_STABILITY_LEVEL" "警告"
    else
        output_result "DIAG_STABILITY_LEVEL" "正常"
    fi
}

# 诊断网络连通性
diagnose_network() {
    local gateway
    gateway=$(ip route 2>/dev/null | grep default | awk '{print $3}' | head -1)

    if [ -n "$gateway" ]; then
        output_result "DIAG_GATEWAY" "$gateway"

        if ping -c 1 -W 2 "$gateway" &>/dev/null; then
            output_result "DIAG_GATEWAY_STATUS" "可达"
        else
            output_result "DIAG_GATEWAY_STATUS" "不可达"
            output_result "DIAG_NETWORK_LEVEL" "警告"
        fi
    fi

    # 检查DNS解析
    if host localhost &>/dev/null || nslookup localhost &>/dev/null; then
        output_result "DIAG_DNS_STATUS" "正常"
    else
        output_result "DIAG_DNS_STATUS" "异常"
    fi
}

# 综合健康评分
calculate_health_score() {
    local score=100

    # 内存扣分
    local mem_info
    mem_info=$(free -m 2>/dev/null | grep "Mem:")
    if [ -n "$mem_info" ]; then
        local total used
        total=$(echo "$mem_info" | awk '{print $2}')
        used=$(echo "$mem_info" | awk '{print $3}')
        local mem_usage=$((used * 100 / total))

        if [ "$mem_usage" -gt 95 ]; then
            score=$((score - 20))
        elif [ "$mem_usage" -gt 85 ]; then
            score=$((score - 10))
        fi
    fi

    # 磁盘扣分
    local disk_usage
    disk_usage=$(df / 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
    if [ -n "$disk_usage" ]; then
        if [ "$disk_usage" -gt 95 ]; then
            score=$((score - 20))
        elif [ "$disk_usage" -gt 85 ]; then
            score=$((score - 10))
        fi
    fi

    # 负载扣分
    local load1
    load1=$(cat /proc/loadavg 2>/dev/null | awk '{print $1}')
    local cpu_count
    cpu_count=$(nproc 2>/dev/null || echo "1")
    if [ -n "$load1" ]; then
        local load_ratio
        load_ratio=$(awk "BEGIN {print $load1 / $cpu_count}")
        if [ $(awk "BEGIN {print ($load_ratio > 4)}") -eq 1 ]; then
            score=$((score - 15))
        elif [ $(awk "BEGIN {print ($load_ratio > 2)}") -eq 1 ]; then
            score=$((score - 5))
        fi
    fi

    output_result "DIAG_HEALTH_SCORE" "$score"

    if [ "$score" -ge 80 ]; then
        output_result "DIAG_HEALTH_LEVEL" "正常"
    elif [ "$score" -ge 60 ]; then
        output_result "DIAG_HEALTH_LEVEL" "警告"
    else
        output_result "DIAG_HEALTH_LEVEL" "严重"
    fi
}

# ==================== 主检测流程 ====================
main() {
    log_info "开始综合诊断检测..."

    set +e

    diagnose_system_load 2>/dev/null || true
    diagnose_memory_pressure 2>/dev/null || true
    diagnose_disk_usage 2>/dev/null || true
    diagnose_docker_status 2>/dev/null || true
    diagnose_system_stability 2>/dev/null || true
    diagnose_network 2>/dev/null || true
    calculate_health_score 2>/dev/null || true

    log_info "综合诊断检测完成"
}

main