#!/bin/bash
################################################################################
# 25_redis_depth.sh — Redis深度检测
# 功能: 检测Redis持久化、内存碎片、缓存命中、主从复制、键空间等深度指标
# 参考: MiddlewareCheck.psm1 / check_redis.sh 移植
################################################################################

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: config.sh not found"; exit 1; fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then source "$LIB_DIR/lib/common.sh"; else echo "ERROR: common.sh not found"; exit 1; fi

REDIS_PWD="${REDIS_PASSWORD:-}"
CONTAINER="${CONTAINERS[redis]:-redis}"
REDIS_CLI="docker exec $CONTAINER redis-cli -a \"$REDIS_PWD\" --no-auth-warning"

# Redis版本
REDIS_VERSION=$(eval $REDIS_CLI INFO server 2>/dev/null | grep redis_version | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_VERSION" "${REDIS_VERSION:-N/A}"

# 运行天数
UPTIME_DAYS=$(eval $REDIS_CLI INFO server 2>/dev/null | grep uptime_in_days | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_UPTIME_DAYS" "${UPTIME_DAYS:-0}"

# 键数量
KEY_COUNT=$(eval $REDIS_CLI DBSIZE 2>/dev/null | grep -E '^[0-9]+$')
output_result "REDIS_DEPTH_KEY_COUNT" "${KEY_COUNT:-0}"

# 内存使用
USED_MEMORY=$(eval $REDIS_CLI INFO memory 2>/dev/null | grep used_memory_human | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_USED_MEMORY" "${USED_MEMORY:-N/A}"

# 内存碎片率
MEM_FRAG=$(eval $REDIS_CLI INFO memory 2>/dev/null | grep mem_fragmentation_ratio | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_MEM_FRAGMENTATION" "${MEM_FRAG:-N/A}"

# 客户端数
CLIENT_COUNT=$(eval $REDIS_CLI INFO clients 2>/dev/null | grep connected_clients | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_CLIENT_COUNT" "${CLIENT_COUNT:-0}"

# 每秒操作数
OPS_PER_SEC=$(eval $REDIS_CLI INFO stats 2>/dev/null | grep instantaneous_ops_per_sec | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_OPS_PER_SEC" "${OPS_PER_SEC:-0}"

# 持久化状态
PERSISTENCE_INFO=$(eval $REDIS_CLI INFO persistence 2>/dev/null)
RDB_COW=$(echo "$PERSISTENCE_INFO" | grep -oP 'rdb_last_cow_size:\K\d+' | head -1)
AOF_ENABLED=$(echo "$PERSISTENCE_INFO" | grep -oP 'aof_enabled:\K\d+' | head -1)

RDB_STATUS="空闲"
if [ -n "$RDB_COW" ] && [ "$RDB_COW" -gt 0 ] 2>/dev/null; then
    RDB_STATUS="备份中"
fi

AOF_STATUS="未启用"
if [ "$AOF_ENABLED" = "1" ]; then
    AOF_STATUS="已启用"
fi
output_result "REDIS_DEPTH_RDB_PERSISTENCE" "$RDB_STATUS"
output_result "REDIS_DEPTH_AOF_PERSISTENCE" "$AOF_STATUS"

# 复制信息
REPL_INFO=$(eval $REDIS_CLI INFO replication 2>/dev/null)
ROLE=$(echo "$REPL_INFO" | grep -oP 'role:\K\w+' | head -1)
CONNECTED_SLAVES=$(echo "$REPL_INFO" | grep -oP 'connected_slaves:\K\d+' | head -1)
MASTER_LINK=$(echo "$REPL_INFO" | grep -oP 'master_link_status:\K\w+' | head -1)

if [ "$ROLE" = "master" ]; then
    output_result "REDIS_DEPTH_REPLICATION_STATUS" "master/slaves:${CONNECTED_SLAVES:-0}"
elif [ "$ROLE" = "slave" ]; then
    output_result "REDIS_DEPTH_REPLICATION_STATUS" "slave/link:${MASTER_LINK:-unknown}"
else
    output_result "REDIS_DEPTH_REPLICATION_STATUS" "${ROLE:-N/A}"
fi
output_result "REDIS_DEPTH_ROLE" "${ROLE:-N/A}"
output_result "REDIS_DEPTH_SLAVES" "${CONNECTED_SLAVES:-0}"

# 缓存命中率
HITS=$(eval $REDIS_CLI INFO stats 2>/dev/null | grep keyspace_hits | cut -d: -f2 | tr -d '\r')
MISSES=$(eval $REDIS_CLI INFO stats 2>/dev/null | grep keyspace_misses | cut -d: -f2 | tr -d '\r')
if [ -n "$HITS" ] && [ -n "$MISSES" ] && [ "$((HITS + MISSES))" -gt 0 ] 2>/dev/null; then
    HIT_RATE=$(awk "BEGIN {printf \"%.2f\", ($HITS*100)/($HITS+$MISSES)}")
    output_result "REDIS_DEPTH_CACHE_HIT_RATE" "$HIT_RATE"
fi

# 拒绝连接数
REJECTED=$(eval $REDIS_CLI INFO stats 2>/dev/null | grep rejected_connections | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_REJECTED_CONNECTIONS" "${REJECTED:-0}"

# 慢日志
SLOW_LOG=$(eval $REDIS_CLI SLOWLOG GET 10 2>/dev/null)
SLOW_COUNT=$(echo "$SLOW_LOG" | awk 'NR%4==3' | wc -l)
output_result "REDIS_DEPTH_SLOWLOG_COUNT" "$SLOW_COUNT"

# 阻塞客户端
BLOCKED_CLIENTS=$(eval $REDIS_CLI INFO clients 2>/dev/null | grep blocked_clients | cut -d: -f2 | tr -d '\r')
output_result "REDIS_DEPTH_BLOCKED_CLIENTS" "${BLOCKED_CLIENTS:-0}"

# 键空间统计
KEYSPACE_INFO=$(eval $REDIS_CLI INFO keyspace 2>/dev/null | grep "^db")
if [ -n "$KEYSPACE_INFO" ]; then
    TOTAL_KEYS=0
    TOTAL_EXPIRES=0
    while IFS=: read -r db_key info; do
        if [[ "$info" =~ keys=([0-9]+) ]]; then
            TOTAL_KEYS=$((TOTAL_KEYS + ${BASH_REMATCH[1]}))
        fi
        if [[ "$info" =~ expires=([0-9]+) ]]; then
            TOTAL_EXPIRES=$((TOTAL_EXPIRES + ${BASH_REMATCH[1]}))
        fi
    done <<< "$KEYSPACE_INFO"
    output_result "REDIS_DEPTH_KEYSPACE_KEYS" "$TOTAL_KEYS"
    output_result "REDIS_DEPTH_KEYSPACE_EXPIRES" "$TOTAL_EXPIRES"
fi

# 配置检查
MAXCLIENTS=$(eval $REDIS_CLI CONFIG GET maxclients 2>/dev/null | tail -1 | tr -d '\r')
TIMEOUT_CFG=$(eval $REDIS_CLI CONFIG GET timeout 2>/dev/null | tail -1 | tr -d '\r')
output_result "REDIS_DEPTH_CONFIG_MAXCLIENTS" "${MAXCLIENTS:-N/A}"
output_result "REDIS_DEPTH_CONFIG_TIMEOUT" "${TIMEOUT_CFG:-0}"

# 集群状态
CLUSTER_INFO=$(eval $REDIS_CLI CLUSTER INFO 2>/dev/null)
CLUSTER_STATE=$(echo "$CLUSTER_INFO" | grep -oP 'cluster_state:\K\w+' | head -1)
if [ -n "$CLUSTER_STATE" ]; then
    CLUSTER_NODES=$(echo "$CLUSTER_INFO" | grep -oP 'cluster_known_nodes:\K\d+' | head -1)
    output_result "REDIS_DEPTH_CLUSTER_STATUS" "$CLUSTER_STATE/${CLUSTER_NODES:-1}"
else
    output_result "REDIS_DEPTH_CLUSTER_STATUS" "Standalone"
fi

# RDB最后保存时间
RDB_LAST_SAVE=$(eval $REDIS_CLI INFO persistence 2>/dev/null | grep rdb_last_save_time | cut -d: -f2 | tr -d '\r')
if [ -n "$RDB_LAST_SAVE" ]; then
    NOW_TS=$(date +%s)
    RDB_AGE_SEC=$((NOW_TS - RDB_LAST_SAVE))
    RDB_AGE_MIN=$((RDB_AGE_SEC / 60))
    output_result "REDIS_DEPTH_RDB_AGE_MIN" "$RDB_AGE_MIN"
fi