#!/bin/bash
# Redis深度检测脚本
# 使用方法: ./redis_depth_check.sh

REDIS_PASSWORD="dNrprU&2S"
CONTAINER="uredis"

# 基础信息
REDIS_VERSION=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO server 2>&1 | grep redis_version | cut -d: -f2 | tr -d '\r')
if [ -n "$REDIS_VERSION" ]; then
    echo "REDIS_VERSION:$REDIS_VERSION"
else
    echo "REDIS_VERSION:N/A"
fi

# 运行时间(天)
UPTIME_DAYS=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO server 2>&1 | grep uptime_in_days | cut -d: -f2 | tr -d '\r')
if [ -n "$UPTIME_DAYS" ]; then
    echo "UPTIME_DAYS:$UPTIME_DAYS"
else
    echo "UPTIME_DAYS:N/A"
fi

# 键数量
KEY_COUNT=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" DBSIZE 2>&1 | grep -v "Warning")
if [ -n "$KEY_COUNT" ] && [[ "$KEY_COUNT" =~ ^[0-9]+$ ]]; then
    echo "KEY_COUNT:$KEY_COUNT"
else
    echo "KEY_COUNT:0"
fi

# 内存使用
MEMORY_INFO=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO memory 2>&1 | grep -E "used_memory_human:|mem_fragmentation_ratio:" | tr -d '\r' | tr '\n' '|' | sed 's/|$//')
if [ -n "$MEMORY_INFO" ]; then
    echo "MEMORY_INFO:$MEMORY_INFO"
else
    echo "MEMORY_INFO:N/A"
fi

# 客户端连接数
CLIENT_COUNT=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO clients 2>&1 | grep connected_clients | cut -d: -f2 | tr -d '\r')
if [ -n "$CLIENT_COUNT" ]; then
    echo "CLIENT_COUNT:$CLIENT_COUNT"
else
    echo "CLIENT_COUNT:0"
fi

# ========== 高优先级功能补充 ==========

# Keyspace信息（各数据库键和过期键统计）
KEYSPACE_INFO=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO keyspace 2>&1 | grep -v "Warning" | grep "^db" | tr -d '\r')
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
            keys=${BASH_REMATCH[1]}
            TOTAL_KEYS=$((TOTAL_KEYS + keys))
        fi
        if [[ "$info" =~ expires=([0-9]+) ]]; then
            expires=${BASH_REMATCH[1]}
            TOTAL_EXPIRES=$((TOTAL_EXPIRES + expires))
        fi
    done <<< "$KEYSPACE_INFO"
    echo "KEYSPACE_DETAIL:Total:$TOTAL_KEYS,Expires:$TOTAL_EXPIRES"
else
    echo "KEYSPACE_DETAIL:N/A"
fi

# 键类型分布采样（采样前100个键）
KEY_TYPE_SAMPLE=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" --scan --count 100 2>&1 | head -100 | xargs -I {} docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" TYPE {} 2>&1 | grep -v "Warning" | sort | uniq -c | awk '{print $2":"$1}' | tr '\n' '|' | sed 's/|$//' | sed 's/ /:/g')
if [ -n "$KEY_TYPE_SAMPLE" ]; then
    echo "KEY_TYPE_DISTRIBUTION:$KEY_TYPE_SAMPLE"
else
    echo "KEY_TYPE_DISTRIBUTION:N/A"
fi

# ========== 中优先级功能补充 ==========

# 持久化信息
PERSISTENCE_INFO=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO persistence 2>&1 | grep -v "Warning" | grep -E "rdb_last_cow_size:|aof_enabled:|rdb_last_save_time:" | tr -d '\r' | tr '\n' '|' | sed 's/|$//')
if [ -n "$PERSISTENCE_INFO" ]; then
    # 解析持久化状态
    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 [ "$RDB_COW" -gt 0 ] 2>/dev/null; then
        RDB_STATUS="备份中"
    fi

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

    echo "PERSISTENCE_STATUS:RDB:$RDB_STATUS,AOF:$AOF_STATUS"
else
    echo "PERSISTENCE_STATUS:N/A"
fi

# 复制信息
REPL_INFO=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO replication 2>&1 | grep -v "Warning" | grep -E "role:|connected_slaves:|master_link_status:" | tr -d '\r' | tr '\n' '|' | sed 's/|$//')
if [ -n "$REPL_INFO" ]; then
    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
        echo "REPLICATION_STATUS:Role:$ROLE,Slaves:${CONNECTED_SLAVES:-0}"
    elif [ "$ROLE" = "slave" ]; then
        echo "REPLICATION_STATUS:Role:$ROLE,MasterLink:${MASTER_LINK:-unknown}"
    else
        echo "REPLICATION_STATUS:Role:$ROLE"
    fi
else
    echo "REPLICATION_STATUS:N/A"
fi

# 慢日志TOP10
SLOW_LOG=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" SLOWLOG GET 10 2>&1 | grep -v "Warning" | head -40)
if [ -n "$SLOW_LOG" ]; then
    # SLOWLOG输出格式：每4行一个记录 (ID, timestamp, duration, command)
    # 我们需要获取所有记录的第3行（持续时间）
    SLOW_COUNT=0
    SLOWEST_TIME=0
    line_num=0
    while IFS= read -r line; do
        line_num=$((line_num + 1))
        # 每第3行是持续时间
        if [ $((line_num % 4)) -eq 3 ]; then
            if [[ "$line" =~ ^[0-9]+$ ]]; then
                duration=$line
                if [ $duration -gt $SLOWEST_TIME ]; then
                    SLOWEST_TIME=$duration
                fi
                SLOW_COUNT=$((SLOW_COUNT + 1))
            fi
        fi
    done <<< "$SLOW_LOG"

    if [ $SLOW_COUNT -gt 0 ]; then
        echo "SLOW_LOG_TOP10:Count:$SLOW_COUNT,Slowest:${SLOWEST_TIME}us"
    else
        echo "SLOW_LOG_TOP10:Count:0"
    fi
else
    echo "SLOW_LOG_TOP10:Count:0"
fi

# 命令统计TOP5
CMD_STATS=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO commandstats 2>&1 | grep -v "Warning" | grep "cmdstat_" | tr -d '\r')
if [ -n "$CMD_STATS" ]; then
    # 提取命令调用次数TOP5
    TOP_COMMANDS=$(echo "$CMD_STATS" | grep -oP 'cmdstat_\K[a-z]+(?=:calls=\d+)' | head -5 | tr '\n' ',' | sed 's/,$//')
    TOP_CALLS=$(echo "$CMD_STATS" | grep -oP 'cmdstat_[a-z]+:calls=\K\d+' | head -5 | tr '\n' ',' | sed 's/,$//')

    if [ -n "$TOP_COMMANDS" ]; then
        # 组合命令和调用次数
        CMD_DETAIL=""
        IFS=',' read -ra CMDS <<< "$TOP_COMMANDS"
        IFS=',' read -ra CALLS <<< "$TOP_CALLS"
        for i in "${!CMDS[@]}"; do
            if [ -n "$CMD_DETAIL" ]; then
                CMD_DETAIL="$CMD_DETAIL,"
            fi
            CMD_DETAIL="$CMD_DETAIL${CMDS[$i]}:${CALLS[$i]}"
        done
        echo "COMMAND_STATS_TOP5:$CMD_DETAIL"
    else
        echo "COMMAND_STATS_TOP5:N/A"
    fi
else
    echo "COMMAND_STATS_TOP5:N/A"
fi

# 客户端列表摘要
CLIENT_LIST=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" CLIENT LIST 2>&1 | grep -v "Warning" | grep "id=" | tr -d '\r')
if [ -n "$CLIENT_LIST" ]; then
    TOTAL_CLIENTS=$(echo "$CLIENT_LIST" | wc -l)
    IDLE_CLIENTS=0
    BLOCKING_CLIENTS=0

    while IFS='=' read -r key value; do
        if [[ "$value" =~ idle=([0-9]+) ]]; then
            idle_time=${BASH_REMATCH[1]}
            if [ "$idle_time" -gt 300 ]; then
                IDLE_CLIENTS=$((IDLE_CLIENTS + 1))
            fi
        fi
        if [[ "$value" =~ blocking=1 ]]; then
            BLOCKING_CLIENTS=$((BLOCKING_CLIENTS + 1))
        fi
    done <<< "$CLIENT_LIST"

    echo "CLIENT_DETAIL:Total:$TOTAL_CLIENTS,IdleOver5min:$IDLE_CLIENTS,Blocking:$BLOCKING_CLIENTS"
else
    echo "CLIENT_DETAIL:N/A"
fi

# 缓存命中率
STATS_INFO=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" INFO stats 2>&1 | grep -v "Warning" | grep -E "keyspace_hits:|keyspace_misses:|rejected_connections:" | tr -d '\r')
if [ -n "$STATS_INFO" ]; then
    HITS=$(echo "$STATS_INFO" | grep keyspace_hits | cut -d: -f2)
    MISSES=$(echo "$STATS_INFO" | grep keyspace_misses | cut -d: -f2)
    REJECTED=$(echo "$STATS_INFO" | grep rejected_connections | cut -d: -f2)

    if [ -n "$HITS" ] && [ -n "$MISSES" ]; then
        TOTAL_REQ=$((HITS + MISSES))
        if [ "$TOTAL_REQ" -gt 0 ]; then
            HIT_RATE=$(awk "BEGIN {printf \"%.2f\", ($HITS * 100) / $TOTAL_REQ}")
        else
            HIT_RATE="0.00"
        fi
        echo "CACHE_HIT_RATE:Hits:$HITS,Misses:$MISSES,Rate:$HIT_RATE%"
    else
        echo "CACHE_HIT_RATE:N/A"
    fi

    if [ -n "$REJECTED" ]; then
        echo "REJECTED_CONNECTIONS:$REJECTED"
    fi
else
    echo "CACHE_HIT_RATE:N/A"
    echo "REJECTED_CONNECTIONS:0"
fi

# 配置检查
CONFIG_MAXCLIENTS=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" CONFIG GET maxclients 2>&1 | grep -v "Warning" | tail -1 | tr -d '\r')
CONFIG_TIMEOUT=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" CONFIG GET timeout 2>&1 | grep -v "Warning" | tail -1 | tr -d '\r')
CONFIG_SAVE=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" CONFIG GET save 2>&1 | grep -v "Warning" | tail -1 | tr -d '\r')

echo "CONFIG_CHECK:MaxClients:$CONFIG_MAXCLIENTS,Timeout:${CONFIG_TIMEOUT}s,Save:$CONFIG_SAVE"

# ========== 补充：集群状态检测 ==========
CLUSTER_INFO=$(docker exec $CONTAINER redis-cli -a "$REDIS_PASSWORD" CLUSTER INFO 2>&1 | grep -v "Warning")
if [ -n "$CLUSTER_INFO" ]; then
    # 解析集群状态
    CLUSTER_STATE=$(echo "$CLUSTER_INFO" | grep -oP 'cluster_state:\K\w+' | head -1)
    CLUSTER_SLOTS_ASSIGNED=$(echo "$CLUSTER_INFO" | grep -oP 'cluster_slots_assigned:\K\d+' | head -1)
    CLUSTER_SLOTS_OK=$(echo "$CLUSTER_INFO" | grep -oP 'cluster_slots_ok:\K\d+' | head -1)
    CLUSTER_KNOWN_NODES=$(echo "$CLUSTER_INFO" | grep -oP 'cluster_known_nodes:\K\d+' | head -1)

    if [ "$CLUSTER_STATE" = "ok" ]; then
        echo "CLUSTER_STATUS:State:OK,Nodes:${CLUSTER_KNOWN_NODES:-1},Slots:${CLUSTER_SLOTS_ASSIGNED:-0}/${CLUSTER_SLOTS_OK:-0}"
    else
        echo "CLUSTER_STATUS:State:${CLUSTER_STATE},Nodes:${CLUSTER_KNOWN_NODES:-1}"
    fi
else
    # 非集群模式，检测单机状态
    echo "CLUSTER_STATUS:Standalone"
fi
