#!/bin/bash
################################################################################
# MySQL基础检测模块
# 功能: 检测MySQL容器状态、版本、连接数、主从状态等
# 作者: Claude Code
# 日期: 2026-05-09
################################################################################

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

# MySQL容器名称
MYSQL_CONTAINER="${CONTAINERS[mysql]}"

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

# 在MySQL容器中执行命令
mysql_exec() {
    docker exec "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PASSWORD" -e "$1" 2>/dev/null
}

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

# 检测MySQL容器状态（使用模糊匹配）
check_mysql_container() {
    local container_status="未运行"
    local level="严重"
    local matched_container=""

    if command -v docker &> /dev/null; then
        # 尝试精确匹配
        matched_container=$(docker ps --format "{{.Names}}" | grep -x "${MYSQL_CONTAINER}" | head -1)

        # 如果精确匹配失败，尝试模糊匹配
        if [ -z "$matched_container" ] && [ -n "$MYSQL_CONTAINER" ]; then
            matched_container=$(docker ps --format "{{.Names}}" | grep -i "${MYSQL_CONTAINER}" | head -1)
        fi

        if [ -n "$matched_container" ]; then
            container_status="运行中 (${matched_container})"
            level="正常"
            # 更新全局变量
            eval "MYSQL_CONTAINER='${matched_container}'"
        else
            # 检查容器是否存在但未运行
            matched_container=$(docker ps -a --format "{{.Names}}" | grep -i "${MYSQL_CONTAINER}" | head -1)
            if [ -n "$matched_container" ]; then
                container_status="已停止 (${matched_container})"
                level="警告"
            fi
        fi
    fi

    output_result "MYSQL_CONTAINER_STATUS" "$container_status"
    output_result "MYSQL_CONTAINER_LEVEL" "$level"

    if [ "$level" != "正常" ]; then
        echo "ERROR:MySQL容器${container_status}"
        return 1
    fi

    return 0
}

# 检测MySQL版本
check_mysql_version() {
    local version=""

    version=$(mysql_exec "SELECT VERSION();" 2>/dev/null | tail -n +2)

    if [ -n "$version" ]; then
        output_result "MYSQL_VERSION" "$version"
    else
        output_result "MYSQL_VERSION" "获取失败"
    fi
}

# 检测MySQL连接状态
check_mysql_connection() {
    local connected="否"

    if mysql_exec "SELECT 1;" &> /dev/null; then
        connected="是"
    fi

    output_result "MYSQL_CONNECTED" "$connected"

    if [ "$connected" = "否" ]; then
        output_result "MYSQL_CONNECTION_LEVEL" "严重"
        echo "ERROR:MySQL连接失败"
    else
        output_result "MYSQL_CONNECTION_LEVEL" "正常"
    fi
}

# 检测MySQL运行时间
check_mysql_uptime() {
    local uptime_days=""

    uptime_days=$(mysql_exec "SHOW STATUS LIKE 'Uptime';" 2>/dev/null | tail -n +2 | awk '{print int($2/86400)}')

    if [ -n "$uptime_days" ]; then
        output_result "MYSQL_UPTIME_DAYS" "$uptime_days"
    else
        output_result "MYSQL_UPTIME_DAYS" "未知"
    fi
}

# 检测MySQL连接数
check_mysql_connections() {
    local current_connections max_connections threads_connected threads_running

    current_connections=$(mysql_exec "SHOW STATUS LIKE 'Threads_connected';" 2>/dev/null | tail -n +2 | awk '{print $2}')
    max_connections=$(mysql_exec "SHOW VARIABLES LIKE 'max_connections';" 2>/dev/null | tail -n +2 | awk '{print $2}')
    threads_running=$(mysql_exec "SHOW STATUS LIKE 'Threads_running';" 2>/dev/null | tail -n +2 | awk '{print $2}')

    if [ -n "$current_connections" ] && [ -n "$max_connections" ]; then
        local usage_percent=0
        if [ "$max_connections" -gt 0 ]; then
            usage_percent=$((current_connections * 100 / max_connections))
        fi

        output_result "MYSQL_CONNECTIONS_CURRENT" "$current_connections"
        output_result "MYSQL_CONNECTIONS_MAX" "$max_connections"
        output_result "MYSQL_CONNECTIONS_USAGE" "${usage_percent}%"
        output_result "MYSQL_THREADS_RUNNING" "$threads_running"

        # 判断连接数状态
        local level="正常"
        if [ "$usage_percent" -ge 90 ]; then
            level="严重"
        elif [ "$usage_percent" -ge 80 ]; then
            level="警告"
        fi

        output_result "MYSQL_CONNECTIONS_LEVEL" "$level"

        if [ "$level" != "正常" ]; then
            echo "ERROR:MySQL连接数使用率过高: ${usage_percent}%"
        fi
    fi
}

# 检测MySQL慢查询
check_mysql_slow_query() {
    local slow_queries slow_launch_time

    slow_queries=$(mysql_exec "SHOW STATUS LIKE 'Slow_queries';" 2>/dev/null | tail -n +2 | awk '{print $2}')
    slow_launch_time=$(mysql_exec "SHOW VARIABLES LIKE 'long_query_time';" 2>/dev/null | tail -n +2 | awk '{print $2}')

    if [ -n "$slow_queries" ]; then
        output_result "MYSQL_SLOW_QUERIES" "$slow_queries"

        if [ -n "$slow_launch_time" ]; then
            output_result "MYSQL_SLOW_QUERY_TIME" "${slow_launch_time}s"
        fi

        # 判断慢查询状态
        local level="正常"
        if [ "$slow_queries" -gt 1000 ]; then
            level="严重"
        elif [ "$slow_queries" -gt 100 ]; then
            level="警告"
        fi

        output_result "MYSQL_SLOW_QUERY_LEVEL" "$level"
    fi
}

# 检测MySQL主从状态
check_mysql_replication() {
    local slave_io_running slave_sql_running seconds_behind_master

    slave_io_running=$(mysql_exec "SHOW SLAVE STATUS\G" 2>/dev/null | grep "Slave_IO_Running:" | awk '{print $2}')
    slave_sql_running=$(mysql_exec "SHOW SLAVE STATUS\G" 2>/dev/null | grep "Slave_SQL_Running:" | awk '{print $2}')
    seconds_behind_master=$(mysql_exec "SHOW SLAVE STATUS\G" 2>/dev/null | grep "Seconds_Behind_Master:" | awk '{print $2}')

    if [ -n "$slave_io_running" ]; then
        output_result "MYSQL_SLAVE_IO" "$slave_io_running"
        output_result "MYSQL_SLAVE_SQL" "$slave_sql_running"

        if [ -n "$seconds_behind_master" ] && [ "$seconds_behind_master" != "NULL" ]; then
            output_result "MYSQL_SLAVE_DELAY" "${seconds_behind_master}s"

            # 判断延迟状态
            local level="正常"
            if [ "$seconds_behind_master" -gt 60 ]; then
                level="严重"
            elif [ "$seconds_behind_master" -gt 10 ]; then
                level="警告"
            fi

            output_result "MYSQL_SLAVE_DELAY_LEVEL" "$level"
        else
            output_result "MYSQL_REPLICATION_STATUS" "未配置或主库"
        fi
    else
        output_result "MYSQL_REPLICATION_STATUS" "未配置"
    fi
}

# 检测MySQL表状态
check_mysql_tables() {
    local open_tables open_tables_definition table_open_cache

    open_tables=$(mysql_exec "SHOW STATUS LIKE 'Open_tables';" 2>/dev/null | tail -n +2 | awk '{print $2}')
    table_open_cache=$(mysql_exec "SHOW VARIABLES LIKE 'table_open_cache';" 2>/dev/null | tail -n +2 | awk '{print $2}')

    if [ -n "$open_tables" ] && [ -n "$table_open_cache" ]; then
        local usage_percent=0
        if [ "$table_open_cache" -gt 0 ]; then
            usage_percent=$((open_tables * 100 / table_open_cache))
        fi

        output_result "MYSQL_OPEN_TABLES" "$open_tables"
        output_result "MYSQL_TABLE_CACHE" "$table_open_cache"
        output_result "MYSQL_TABLE_USAGE" "${usage_percent}%"
    fi
}

# 检测MySQL InnoDB状态
check_mysql_innodb() {
    local innodb_buffer_pool_size innodb_buffer_pool_reads innodb_buffer_pool_read_requests

    innodb_buffer_pool_size=$(mysql_exec "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" 2>/dev/null | tail -n +2 | awk '{print int($2/1024/1024)"MB"}')
    innodb_buffer_pool_reads=$(mysql_exec "SHOW STATUS LIKE 'Innodb_buffer_pool_reads';" 2>/dev/null | tail -n +2 | awk '{print $2}')
    innodb_buffer_pool_read_requests=$(mysql_exec "SHOW STATUS LIKE 'Innodb_buffer_pool_read_requests';" 2>/dev/null | tail -n +2 | awk '{print $2}')

    if [ -n "$innodb_buffer_pool_size" ]; then
        output_result "MYSQL_INNODB_BUFFER_POOL" "$innodb_buffer_pool_size"
    fi

    if [ -n "$innodb_buffer_pool_reads" ] && [ -n "$innodb_buffer_pool_read_requests" ]; then
        if [ "$innodb_buffer_pool_read_requests" -gt 0 ]; then
            local hit_rate=$((100 - (innodb_buffer_pool_reads * 100 / innodb_buffer_pool_read_requests)))
            output_result "MYSQL_INNODB_HIT_RATE" "${hit_rate}%"

            # �判断缓存命中率
            local level="正常"
            if [ "$hit_rate" -lt 90 ]; then
                level="严重"
            elif [ "$hit_rate" -lt 95 ]; then
                level="警告"
            fi

            output_result "MYSQL_INNODB_HIT_LEVEL" "$level"
        fi
    fi
}

# 检测MySQL字符集
check_mysql_charset() {
    local character_set collation

    character_set=$(mysql_exec "SHOW VARIABLES LIKE 'character_set_server';" 2>/dev/null | tail -n +2 | awk '{print $2}')
    collation=$(mysql_exec "SHOW VARIABLES LIKE 'collation_server';" 2>/dev/null | tail -n +2 | awk '{print $2}')

    if [ -n "$character_set" ]; then
        output_result "MYSQL_CHARSET" "$character_set"
    fi

    if [ -n "$collation" ]; then
        output_result "MYSQL_COLLATION" "$collation"
    fi
}

# ==================== 主检测流程 ====================
main() {
    log_info "开始MySQL基础检测..."

    # 检查容器状态
    if ! check_mysql_container; then
        log_warn "MySQL容器未运行，跳过其他检测"
        return
    fi

    # 执行各项检测
    check_mysql_version
    check_mysql_connection
    check_mysql_uptime
    check_mysql_connections
    check_mysql_slow_query
    check_mysql_replication
    check_mysql_tables
    check_mysql_innodb
    check_mysql_charset

    log_info "MySQL基础检测完成"
}

# 执行主函数
main
