#!/bin/bash
################################################################################
# UStorage容器监测模块
# 功能: 检测ustorage容器运行状态、健康检查、存储容量与IO
# 作者: 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

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

# 检测容器运行状态
check_container_status() {
    local container_name
    container_name=$(resolve_container ustorge 2>/dev/null)

    if [ -z "$container_name" ]; then
        # 尝试其他可能的名称
        container_name=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE "ustorage|storage" | head -1)
    fi

    if [ -z "$container_name" ]; then
        output_result "USTORAGE_CONTAINER_STATUS" "未运行"
        output_result "USTORAGE_CONTAINER_LEVEL" "严重"
        return 1
    fi

    output_result "USTORAGE_CONTAINER_NAME" "$container_name"

    # 检查容器状态
    local status
    status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null)

    if [ "$status" = "running" ]; then
        output_result "USTORAGE_CONTAINER_STATUS" "运行中"
        output_result "USTORAGE_CONTAINER_LEVEL" "正常"
    else
        output_result "USTORAGE_CONTAINER_STATUS" "$status"
        output_result "USTORAGE_CONTAINER_LEVEL" "严重"
        return 1
    fi

    # 重启次数
    local restart_count
    restart_count=$(docker inspect --format='{{.RestartCount}}' "$container_name" 2>/dev/null)
    output_result "USTORAGE_RESTART_COUNT" "${restart_count:-0}"

    if [ "${restart_count:-0}" -gt 3 ]; then
        output_result "USTORAGE_RESTART_LEVEL" "警告"
    else
        output_result "USTORAGE_RESTART_LEVEL" "正常"
    fi

    # 运行时长（秒）
    local start_time
    start_time=$(docker inspect --format='{{.State.StartedAt}}' "$container_name" 2>/dev/null)
    if [ -n "$start_time" ]; then
        local start_epoch uptime_seconds
        start_epoch=$(date -d "$start_time" +%s 2>/dev/null || echo "0")
        if [ "$start_epoch" -gt 0 ]; then
            uptime_seconds=$(( $(date +%s) - start_epoch ))
            output_result "USTORAGE_UPTIME_SECONDS" "$uptime_seconds"
        fi
    fi

    return 0
}

# 检测容器资源使用
check_container_resources() {
    local container_name
    container_name=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE "ustorage|storage" | head -1)

    if [ -z "$container_name" ]; then
        return 1
    fi

    # CPU使用率
    local cpu_percent
    cpu_percent=$(docker stats --no-stream --format '{{.CPUPerc}}' "$container_name" 2>/dev/null | tr -d '%')
    if [ -n "$cpu_percent" ]; then
        output_result "USTORAGE_CPU_USAGE" "$cpu_percent"
    fi

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

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

    # 网络IO
    local net_io
    net_io=$(docker stats --no-stream --format '{{.NetIO}}' "$container_name" 2>/dev/null)
    if [ -n "$net_io" ]; then
        output_result "USTORAGE_NET_IO" "$net_io"
    fi

    # 磁盘IO
    local block_io
    block_io=$(docker stats --no-stream --format '{{.BlockIO}}' "$container_name" 2>/dev/null)
    if [ -n "$block_io" ]; then
        output_result "USTORAGE_BLOCK_IO" "$block_io"
    fi
}

# 检测服务健康状态（HTTP健康检查）
check_health_endpoint() {
    local container_name
    container_name=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE "ustorage|storage" | head -1)

    if [ -z "$container_name" ]; then
        return 1
    fi

    # 获取容器IP
    local container_ip
    container_ip=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name" 2>/dev/null)

    if [ -z "$container_ip" ]; then
        output_result "USTORAGE_HEALTH_CHECK" "无法获取IP"
        return 1
    fi

    output_result "USTORAGE_CONTAINER_IP" "$container_ip"

    # 尝试常见的健康检查端口
    local ports="8080 80 9000 3000"
    local health_ok=false
    local response_time

    for port in $ports; do
        # 检查端口是否监听
        if timeout 5 bash -c "echo >/dev/tcp/$container_ip/$port" 2>/dev/null; then
            output_result "USTORAGE_SERVICE_PORT" "$port"

            # 尝试健康检查接口
            local start_time end_time
            start_time=$(date +%s%N 2>/dev/null || echo "0")

            if curl -sf "http://$container_ip:$port/health" -o /dev/null --connect-timeout 5 --max-time 10 2>/dev/null; then
                health_ok=true
                end_time=$(date +%s%N 2>/dev/null || echo "0")
                response_time=$(( (end_time - start_time) / 1000000 ))
                output_result "USTORAGE_HEALTH_CHECK" "正常"
                output_result "USTORAGE_RESPONSE_TIME" "${response_time}ms"
                output_result "USTORAGE_HEALTH_LEVEL" "正常"
                break
            elif curl -sf "http://$container_ip:$port/" -o /dev/null --connect-timeout 5 --max-time 10 2>/dev/null; then
                health_ok=true
                end_time=$(date +%s%N 2>/dev/null || echo "0")
                response_time=$(( (end_time - start_time) / 1000000 ))
                output_result "USTORAGE_HEALTH_CHECK" "正常"
                output_result "USTORAGE_RESPONSE_TIME" "${response_time}ms"
                output_result "USTORAGE_HEALTH_LEVEL" "正常"
                break
            fi
        fi
    done

    if [ "$health_ok" = false ]; then
        output_result "USTORAGE_HEALTH_CHECK" "无法访问"
        output_result "USTORAGE_HEALTH_LEVEL" "警告"
    fi
}

# 检测存储容量（通过容器内命令）
check_storage_capacity() {
    local container_name
    container_name=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE "ustorage|storage" | head -1)

    if [ -z "$container_name" ]; then
        return 1
    fi

    # 检查容器内数据目录大小
    local data_dirs="/data /storage /var/lib/storage"

    for dir in $data_dirs; do
        # 尝试在容器内执行命令
        local dir_size
        dir_size=$(docker exec "$container_name" du -sh "$dir" 2>/dev/null | awk '{print $1}')

        if [ -n "$dir_size" ]; then
            output_result "USTORAGE_DATA_SIZE" "$dir_size"
            break
        fi
    done

    # 检查磁盘使用率（容器视角）
    local disk_usage
    disk_usage=$(docker exec "$container_name" df -h / 2>/dev/null | awk 'NR==2 {print $5}' | tr -d '%')

    if [ -n "$disk_usage" ]; then
        output_result "USTORAGE_DISK_USAGE" "$disk_usage"

        if [ "$disk_usage" -gt 90 ]; then
            output_result "USTORAGE_DISK_LEVEL" "严重"
        elif [ "$disk_usage" -gt 80 ]; then
            output_result "USTORAGE_DISK_LEVEL" "警告"
        else
            output_result "USTORAGE_DISK_LEVEL" "正常"
        fi
    fi

    # 检查inode使用率
    local inode_usage
    inode_usage=$(docker exec "$container_name" df -i / 2>/dev/null | awk 'NR==2 {print $5}' | tr -d '%')

    if [ -n "$inode_usage" ]; then
        output_result "USTORAGE_INODE_USAGE" "$inode_usage"
    fi
}

# 检测日志大小
check_log_size() {
    local container_name
    container_name=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE "ustorage|storage" | head -1)

    if [ -z "$container_name" ]; then
        return 1
    fi

    # 检查容器日志文件大小
    local log_path
    log_path=$(docker inspect --format='{{.LogPath}}' "$container_name" 2>/dev/null)

    if [ -n "$log_path" ] && [ -f "$log_path" ]; then
        local log_size
        log_size=$(du -sh "$log_path" 2>/dev/null | awk '{print $1}')

        if [ -n "$log_size" ]; then
            output_result "USTORAGE_LOG_SIZE" "$log_size"

            # 检查是否超过500MB
            local log_bytes
            log_bytes=$(stat -c%s "$log_path" 2>/dev/null || echo "0")
            if [ "$log_bytes" -gt 524288000 ]; then
                output_result "USTORAGE_LOG_LEVEL" "警告"
            else
                output_result "USTORAGE_LOG_LEVEL" "正常"
            fi
        fi
    fi
}

# ==================== 主检测流程 ====================
main() {
    log_info "开始UStorage容器监测..."

    # 执行各项检测
    check_container_status && {
        check_container_resources
        check_health_endpoint
        check_storage_capacity
        check_log_size
    }

    log_info "UStorage容器监测完成"
}

# 执行主函数
main