#!/bin/bash
################################################################################
# 时间同步检测模块
# 功能: 检测NTP同步状态、时钟偏差、SSL证书有效期等
# 作者: 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

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

# 检测NTP同步状态
check_ntp_status() {
    if command -v timedatectl &>/dev/null; then
        local timedate_output
        timedate_output=$(timedatectl status 2>/dev/null)

        if echo "$timedate_output" | grep -q "NTP service: active"; then
            output_result "NTP_SERVICE_STATUS" "运行中"
        elif echo "$timedate_output" | grep -q "NTP enabled: yes"; then
            output_result "NTP_SERVICE_STATUS" "已启用"
        else
            output_result "NTP_SERVICE_STATUS" "未启用"
            output_result "NTP_SERVICE_LEVEL" "警告"
        fi

        if echo "$timedate_output" | grep -q "System clock synchronized: yes"; then
            output_result "SYSTEM_CLOCK_SYNC" "已同步"
        else
            output_result "SYSTEM_CLOCK_SYNC" "未同步"
            output_result "SYSTEM_CLOCK_SYNC_LEVEL" "警告"
        fi
    fi

    # 检查NTP守护进程
    if systemctl is-active --quiet chronyd 2>/dev/null; then
        output_result "NTP_DAEMON" "chronyd"
    elif systemctl is-active --quiet ntpd 2>/dev/null; then
        output_result "NTP_DAEMON" "ntpd"
    elif systemctl is-active --quiet systemd-timesyncd 2>/dev/null; then
        output_result "NTP_DAEMON" "systemd-timesyncd"
    fi
}

# 检测时钟同步源
check_ntp_sources() {
    local sources=""
    local current_source=""

    if command -v chronyc &>/dev/null; then
        local chronyc_sources
        chronyc_sources=$(chronyc sources 2>/dev/null)

        if [ -n "$chronyc_sources" ]; then
            sources=$(echo "$chronyc_sources" | grep "^[\*\+\#]" | awk '{print $2}' | tr '\n' ',' | sed 's/,$//')
            current_source=$(echo "$chronyc_sources" | grep "^\*" | awk '{print $2}' | head -1)

            output_result "NTP_SOURCES" "$sources"

            if [ -n "$current_source" ]; then
                output_result "NTP_CURRENT_SOURCE" "$current_source"
            fi
        fi
    fi

    if [ -z "$sources" ] && command -v ntpq &>/dev/null; then
        local ntpq_output
        ntpq_output=$(ntpq -p 2>/dev/null)

        if [ -n "$ntpq_output" ]; then
            sources=$(echo "$ntpq_output" | grep "^[\*\+\+\#]" | awk '{print $1}' | tr '\n' ',' | sed 's/,$//')
            current_source=$(echo "$ntpq_output" | grep "^\*" | awk '{print $1}' | head -1)

            output_result "NTP_SOURCES" "$sources"

            if [ -n "$current_source" ]; then
                output_result "NTP_CURRENT_SOURCE" "$current_source"
            fi
        fi
    fi
}

# 检测时钟偏差
check_clock_offset() {
    local offset_ms="未知"
    local offset_level="正常"

    if command -v chronyc &>/dev/null; then
        local chronyc_tracking
        chronyc_tracking=$(chronyc tracking 2>/dev/null)

        if [ -n "$chronyc_tracking" ]; then
            offset_ms=$(echo "$chronyc_tracking" | grep "RMS offset" | awk '{print $4}')

            if [ -n "$offset_ms" ] && [ "$offset_ms" != "未知" ]; then
                output_result "NTP_OFFSET_MS" "$offset_ms"

                local offset_abs
                offset_abs=$(awk "BEGIN {print ($offset_ms < 0) ? -$offset_ms : $offset_ms}")

                if [ "$offset_abs" -gt 5000000 ]; then
                    offset_level="严重"
                elif [ "$offset_abs" -gt 1000000 ]; then
                    offset_level="警告"
                fi
            fi
        fi
    fi

    output_result "NTP_OFFSET_LEVEL" "$offset_level"
}

# 检测系统时间
check_system_time() {
    local system_date
    system_date=$(date 2>/dev/null)
    output_result "SYSTEM_DATETIME" "$system_date"

    local system_timestamp
    system_timestamp=$(date +%s 2>/dev/null)
    output_result "SYSTEM_TIMESTAMP" "$system_timestamp"

    local timezone
    timezone=$(timedatectl status 2>/dev/null | grep "Time zone" | awk '{print $3}')
    [ -n "$timezone" ] && output_result "SYSTEM_TIMEZONE" "$timezone"
}

# 检测HTTPS证书有效期
check_https_cert_expiry() {
    local cert_files=""

    for cert_path in /etc/nginx/ssl/*.crt /etc/nginx/certs/*.crt /etc/ssl/certs/*.crt; do
        if [ -f "$cert_path" ]; then
            cert_files="${cert_files}${cert_path},"
        fi
    done

    cert_files=$(echo "$cert_files" | sed 's/,$//')

    if [ -n "$cert_files" ]; then
        local min_days=9999

        for cert in ${cert_files//,/ }; do
            if [ -f "$cert" ]; then
                local expiry_date
                expiry_date=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2)

                if [ -n "$expiry_date" ]; then
                    local expiry_timestamp
                    expiry_timestamp=$(date -d "$expiry_date" +%s 2>/dev/null)

                    if [ -n "$expiry_timestamp" ]; then
                        local current_timestamp
                        current_timestamp=$(date +%s)
                        local days_left=$(( (expiry_timestamp - current_timestamp) / 86400 ))

                        if [ "$days_left" -lt "$min_days" ]; then
                            min_days=$days_left
                        fi
                    fi
                fi
            fi
        done

        if [ "$min_days" -lt 9999 ]; then
            output_result "HTTPS_CERT_MIN_DAYS" "$min_days"

            if [ "$min_days" -le 7 ]; then
                output_result "HTTPS_CERT_LEVEL" "严重"
            elif [ "$min_days" -le 30 ]; then
                output_result "HTTPS_CERT_LEVEL" "警告"
            else
                output_result "HTTPS_CERT_LEVEL" "正常"
            fi
        fi
    else
        output_result "HTTPS_CERT_STATUS" "未找到证书文件"
    fi
}

# 检测系统运行时间
check_uptime() {
    local uptime_seconds
    uptime_seconds=$(cat /proc/uptime 2>/dev/null | awk '{print $1}' | cut -d. -f1)

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

# ==================== 主检测流程 ====================
main() {
    log_info "开始时间同步检测..."

    set +e

    check_ntp_status 2>/dev/null || true
    check_ntp_sources 2>/dev/null || true
    check_clock_offset 2>/dev/null || true
    check_system_time 2>/dev/null || true
    check_https_cert_expiry 2>/dev/null || true
    check_uptime 2>/dev/null || true

    log_info "时间同步检测完成"
}

main