#!/bin/bash
################################################################################
# Nginx深度检测模块
# 功能: 深度检测Nginx连接数、请求统计、性能指标、配置详情等
# 作者: 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

# Nginx容器名称
NGINX_CONTAINER="${CONTAINERS[nginx]}"

# ==================== 辅助函数 ====================

# 在Nginx容器中执行命令
nginx_exec() {
    docker exec "$NGINX_CONTAINER" $@ 2>/dev/null
}

# ==================== 深度检测函数 ====================

# 检测Nginx版本详情
check_nginx_version_detail() {
    local nginx_version

    # 方法1: 直接在容器内执行nginx -v
    nginx_version=$(nginx_exec sh -c "nginx -v 2>&1" | grep "nginx version" | sed 's/.*nginx\///' | sed 's/ $//')

    # 方法2: 如果方法1失败，尝试使用which找到nginx路径
    if [ -z "$nginx_version" ]; then
        local nginx_path
        nginx_path=$(nginx_exec which nginx 2>/dev/null)
        if [ -n "$nginx_path" ]; then
            nginx_version=$(nginx_exec "$nginx_path" -v 2>&1 | grep "nginx version" | sed 's/.*nginx\///' | sed 's/ $//')
        fi
    fi

    # 方法3: 如果仍然失败，从容器标签获取
    if [ -z "$nginx_version" ]; then
        local image_version
        image_version=$(docker inspect --format='{{.Config.Image}}' "$NGINX_CONTAINER" 2>/dev/null | grep -oE ':[0-9.]+' | sed 's/://')
        if [ -n "$image_version" ]; then
            nginx_version="$image_version"
        fi
    fi

    if [ -n "$nginx_version" ]; then
        output_result "NGINX_VERSION" "$nginx_version"
    fi
}

# 检测Nginx连接统计
check_nginx_connections() {
    # 从状态页面获取连接信息
    local status_data
    status_data=$(nginx_exec curl -s localhost/nginx_status 2>/dev/null)

    if [ -n "$status_data" ]; then
        # 解析active connections
        local active_conn
        active_conn=$(echo "$status_data" | grep "Active connections" | awk '{print $3}' || echo "0")
        output_result "NGINX_ACTIVE_CONNECTIONS" "$active_conn"

        # 解析accepted connections
        local accepted_conn
        accepted_conn=$(echo "$status_data" | awk 'NR==3 {print $1}' || echo "0")
        output_result "NGINX_ACCEPTED_CONNECTIONS" "$accepted_conn"

        # 解析handled connections
        local handled_conn
        handled_conn=$(echo "$status_data" | awk 'NR==3 {print $2}' || echo "0")
        output_result "NGINX_HANDLED_CONNECTIONS" "$handled_conn"

        # 解析请求数
        local requests
        requests=$(echo "$status_data" | awk 'NR==3 {print $3}' || echo "0")
        output_result "NGINX_REQUESTS_TOTAL" "$requests"
    fi
}

# 检测Nginx进程状态
check_nginx_process() {
    local nginx_pid
    nginx_pid=$(nginx_exec cat /var/run/nginx.pid 2>/dev/null)

    if [ -n "$nginx_pid" ]; then
        output_result "NGINX_PID" "$nginx_pid"

        # 获取进程数（master + worker）- 使用多种方法
        local process_count

        # 方法1: 使用pgrep查找nginx进程
        process_count=$(nginx_exec pgrep -f nginx 2>/dev/null | wc -l)

        # 方法2: 如果pgrep失败，使用ps aux
        if [ "$process_count" -eq 0 ]; then
            process_count=$(nginx_exec ps aux 2>/dev/null | grep -v grep | grep -c "[n]ginx" || echo "0")
        fi

        if [ "$process_count" -gt 0 ]; then
            output_result "NGINX_PROCESSES" "$process_count"
        fi
    fi
}

# 检测Nginx监听端口
check_nginx_listening() {
    local listening_ports
    listening_ports=$(nginx_exec ss -tlnp 2>/dev/null | grep nginx | awk '{print $4}' | grep -oE '[0-9]+$' | sort -u | tr '\n' ',' | sed 's/,$//')

    if [ -z "$listening_ports" ]; then
        listening_ports=$(nginx_exec netstat -tlnp 2>/dev/null | grep nginx | awk '{print $4}' | grep -oE '[0-9]+$' | sort -u | tr '\n' ',' | sed 's/,$//')
    fi

    if [ -n "$listening_ports" ]; then
        output_result "NGINX_LISTENING_PORTS" "$listening_ports"
    fi
}

# 检测Nginx配置详情
check_nginx_config_detail() {
    # 测试配置文件
    local config_test
    config_test=$(nginx_exec nginx -t 2>&1)

    if echo "$config_test" | grep -q "successful"; then
        output_result "NGINX_CONFIG_STATUS" "正常"
        output_result "NGINX_CONFIG_LEVEL" "正常"
    else
        output_result "NGINX_CONFIG_STATUS" "异常"
        output_result "NGINX_CONFIG_LEVEL" "严重"

        # 获取错误信息
        local error_msg
        error_msg=$(echo "$config_test" | grep "error" | head -1)
        [ -n "$error_msg" ] && output_result "NGINX_CONFIG_ERROR" "$error_msg"
    fi
}

# 检测Nginx worker进程配置
check_nginx_worker_config() {
    # 获取worker进程数
    local worker_processes
    worker_processes=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep 'worker_processes' | grep -v '#' | awk '{print \$2}' | head -1")

    if [ -n "$worker_processes" ]; then
        output_result "NGINX_WORKER_PROCESSES" "$worker_processes"
    fi

    # 获取worker连接数
    local worker_connections
    worker_connections=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep 'worker_connections' | grep -v '#' | awk '{print \$2}' | head -1")

    if [ -n "$worker_connections" ]; then
        output_result "NGINX_WORKER_CONNECTIONS" "$worker_connections"
    fi
}

# 检测Nginx日志文件
check_nginx_logs() {
    # 检查access log大小
    local access_log_size
    access_log_size=$(nginx_exec ls -lh /var/log/nginx/access.log 2>/dev/null | awk '{print $5}')

    if [ -n "$access_log_size" ]; then
        output_result "NGINX_ACCESS_LOG_SIZE" "$access_log_size"
    fi

    # 检查error log大小
    local error_log_size
    error_log_size=$(nginx_exec ls -lh /var/log/nginx/error.log 2>/dev/null | awk '{print $5}')

    if [ -n "$error_log_size" ]; then
        output_result "NGINX_ERROR_LOG_SIZE" "$error_log_size"
    fi

    # 统计最近的错误数量（最近100行）
    local recent_errors
    recent_errors=$(nginx_exec tail -100 /var/log/nginx/error.log 2>/dev/null | grep -c "error" || echo "0")
    output_result "NGINX_RECENT_ERRORS" "$recent_errors"
}

# 检测Nginx SSL证书状态
check_nginx_ssl() {
    # 检查是否启用了SSL
    local ssl_enabled
    ssl_enabled=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep -c 'listen.*ssl'" || echo "0")

    if [ "$ssl_enabled" -gt 0 ]; then
        output_result "NGINX_SSL_ENABLED" "是"

        # 获取SSL证书过期时间（如果有443端口）
        local cert_expiry
        cert_expiry=$(nginx_exec openssl x509 -in /etc/nginx/ssl/nginx.crt -noout -enddate 2>/dev/null | cut -d= -f2)

        if [ -n "$cert_expiry" ]; then
            output_result "NGINX_SSL_CERT_EXPIRY" "$cert_expiry"
        fi
    else
        output_result "NGINX_SSL_ENABLED" "否"
    fi
}

# 检测Nginx缓存状态
check_nginx_cache() {
    # 检查是否配置了缓存
    local cache_enabled
    cache_enabled=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep -c 'proxy_cache_path'" || echo "0")

    if [ "$cache_enabled" -gt 0 ]; then
        output_result "NGINX_CACHE_ENABLED" "是"

        # 获取缓存路径
        local cache_path
        cache_path=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep 'proxy_cache_path' | grep -v '#' | awk '{print \$2}' | head -1")

        if [ -n "$cache_path" ]; then
            output_result "NGINX_CACHE_PATH" "$cache_path"
        fi
    else
        output_result "NGINX_CACHE_ENABLED" "否"
    fi
}

# 检测Nginx upstream状态
check_nginx_upstream() {
    # 检查upstream配置
    local upstream_count
    upstream_count=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep -c 'upstream'" || echo "0")

    if [ "$upstream_count" -gt 0 ]; then
        output_result "NGINX_UPSTREAM_COUNT" "$upstream_count"

        # 获取upstream名称列表
        local upstreams
        upstreams=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep 'upstream' | grep -v '#' | awk '{print \$2}' | tr '\n' ',' | sed 's/,$//'")
        [ -n "$upstreams" ] && output_result "NGINX_UPSTREAMS" "$upstreams"
    else
        output_result "NGINX_UPSTREAM_COUNT" "0"
    fi
}

# 检测Nginx server块配置
check_nginx_server_blocks() {
    # 统计server块数量
    local server_count
    server_count=$(nginx_exec sh -c "nginx -T 2>/dev/null | grep -c 'server_name'" || echo "0")

    if [ -n "$server_count" ]; then
        output_result "NGINX_SERVER_BLOCKS" "$server_count"
    fi
}

# 检测Nginx访问日志状态码分布
check_nginx_access_log_stats() {
    local access_log="/var/log/nginx/access.log"

    # 检查日志文件是否存在
    if ! nginx_exec test -f "$access_log" 2>/dev/null; then
        return
    fi

    # 统计最近1000行日志的状态码分布
    local status_2xx status_3xx status_4xx status_5xx
    status_2xx=$(nginx_exec tail -1000 "$access_log" 2>/dev/null | awk '$9 ~ /^2/ {count++} END {print count+0}')
    status_3xx=$(nginx_exec tail -1000 "$access_log" 2>/dev/null | awk '$9 ~ /^3/ {count++} END {print count+0}')
    status_4xx=$(nginx_exec tail -1000 "$access_log" 2>/dev/null | awk '$9 ~ /^4/ {count++} END {print count+0}')
    status_5xx=$(nginx_exec tail -1000 "$access_log" 2>/dev/null | awk '$9 ~ /^5/ {count++} END {print count+0}')

    output_result "NGINX_STATUS_2XX" "${status_2xx:-0}"
    output_result "NGINX_STATUS_3XX" "${status_3xx:-0}"
    output_result "NGINX_STATUS_4XX" "${status_4xx:-0}"
    output_result "NGINX_STATUS_5XX" "${status_5xx:-0}"

    # 计算错误率
    local total_requests=$((status_2xx + status_3xx + status_4xx + status_5xx))
    if [ "$total_requests" -gt 0 ]; then
        local error_rate=$(( (status_4xx + status_5xx) * 100 / total_requests ))
        output_result "NGINX_ERROR_RATE" "${error_rate}%"
    fi
}

# 检测Nginx运行时间
check_nginx_uptime() {
    local nginx_pid
    nginx_pid=$(nginx_exec cat /var/run/nginx.pid 2>/dev/null)

    if [ -n "$nginx_pid" ]; then
        # 获取进程运行时间
        local uptime_seconds
        uptime_seconds=$(nginx_exec ps -p "$nginx_pid" -o etimes= 2>/dev/null | tr -d ' ')

        if [ -n "$uptime_seconds" ] && [ "$uptime_seconds" -gt 0 ]; then
            local uptime_days=$((uptime_seconds / 86400))
            output_result "NGINX_UPTIME_DAYS" "$uptime_days"
        fi
    fi
}

# 检测Nginx容器资源使用
check_nginx_resources() {
    # CPU使用率
    local cpu_percent
    cpu_percent=$(docker stats --no-stream --format '{{.CPUPerc}}' "$NGINX_CONTAINER" 2>/dev/null | tr -d '%')
    if [ -n "$cpu_percent" ]; then
        output_result "NGINX_CPU_USAGE" "$cpu_percent"
    fi

    # 内存使用
    local mem_usage mem_percent
    mem_usage=$(docker stats --no-stream --format '{{.MemUsage}}' "$NGINX_CONTAINER" 2>/dev/null)
    if [ -n "$mem_usage" ]; then
        output_result "NGINX_MEMORY_USAGE" "$mem_usage"
    fi

    mem_percent=$(docker stats --no-stream --format '{{.MemPerc}}' "$NGINX_CONTAINER" 2>/dev/null | tr -d '%')
    if [ -n "$mem_percent" ]; then
        output_result "NGINX_MEMORY_PERCENT" "$mem_percent"
    fi
}

# ==================== 主检测流程 ====================
main() {
    log_info "开始Nginx深度检测..."

    # 检查容器状态（使用模糊匹配）
    local matched_container=""
    matched_container=$(docker ps --format "{{.Names}}" | grep -x "${NGINX_CONTAINER}" | head -1)

    if [ -z "$matched_container" ] && [ -n "$NGINX_CONTAINER" ]; then
        matched_container=$(docker ps --format "{{.Names}}" | grep -i "${NGINX_CONTAINER}" | head -1)
    fi

    if [ -z "$matched_container" ]; then
        log_warn "Nginx容器未运行"
        output_result "NGINX_CONTAINER_STATUS" "未运行"
        return 1
    fi

    # 更新为实际容器名
    eval "NGINX_CONTAINER='${matched_container}'"
    output_result "NGINX_CONTAINER_STATUS" "运行中 (${NGINX_CONTAINER})"

    # 执行各项深度检测
    check_nginx_version_detail 2>/dev/null || true
    check_nginx_connections 2>/dev/null || true
    check_nginx_process 2>/dev/null || true
    check_nginx_listening 2>/dev/null || true
    check_nginx_config_detail 2>/dev/null || true
    check_nginx_worker_config 2>/dev/null || true
    check_nginx_logs 2>/dev/null || true
    check_nginx_ssl 2>/dev/null || true
    check_nginx_cache 2>/dev/null || true
    check_nginx_upstream 2>/dev/null || true
    check_nginx_server_blocks 2>/dev/null || true
    check_nginx_access_log_stats 2>/dev/null || true
    check_nginx_uptime 2>/dev/null || true
    check_nginx_resources 2>/dev/null || true

    log_info "Nginx深度检测完成"
}

# 执行主函数
main