#!/bin/bash

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

REPORT_SERVER="https://vps-top.ru/api/report"
REPORT_TOKEN="vps-top-secret-token-2025"

ISSUES=0
IS_VIRTUALIZED=1

declare -A RESULTS

print_header() {
    echo -e "\n${CYAN}━ $1${NC}"
}

print_result() {
    echo -e "${CYAN}  ├─ $1:${NC} ${2}"
}

print_result_colored() {
    echo -e "${CYAN}  ├─ $1:${NC} ${GREEN}$2${NC}"
}

print_warn() {
    echo -e "${CYAN}  ├─ $1:${NC} ${YELLOW}$2${NC}"
    ((ISSUES++))
}

print_error() {
    echo -e "${CYAN}  ├─ $1:${NC} ${RED}$2${NC}"
    ((ISSUES++))
}

format_number() {
    local num=$1
    local unit=$2
    if [[ $num == *"k"* ]]; then
        num=$(echo "$num" | sed 's/k//')
        num=$(echo "scale=1; $num * 1000" | bc 2>/dev/null)
    fi
    if [ ! -z "$num" ] && [ "$num" != "0" ]; then
        num=$(echo "scale=1; $num / 1" | bc 2>/dev/null)
        echo "${num}${unit}"
    else
        echo "N/A"
    fi
}

get_os_info() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        echo "$PRETTY_NAME"
    elif [ -f /etc/lsb-release ]; then
        . /etc/lsb-release
        echo "$DISTRIB_DESCRIPTION"
    else
        echo "Unknown"
    fi
}

get_isp_info() {
    local org city country
    org=$(timeout 5 curl -s http://ipinfo.io/org 2>/dev/null || timeout 5 wget -qO- http://ipinfo.io/org 2>/dev/null)
    city=$(timeout 5 curl -s http://ipinfo.io/city 2>/dev/null || timeout 5 wget -qO- http://ipinfo.io/city 2>/dev/null)
    country=$(timeout 5 curl -s http://ipinfo.io/country 2>/dev/null || timeout 5 wget -qO- http://ipinfo.io/country 2>/dev/null)
    if [ ! -z "$org" ]; then ISP_ORG="$org"; else ISP_ORG="N/A"; fi
    if [ ! -z "$city" ] && [ ! -z "$country" ]; then ISP_LOCATION="$city / $country"; else ISP_LOCATION="N/A"; fi
}

check_dependencies() {
    # Проверяем флаг что пакеты уже установлены
    if [ -f "/tmp/vps-top-deps-installed" ]; then
        return 0
    fi
    
    PACKAGES="sysbench fio wget curl bc ioping p7zip-full openssl"
    MISSING=""
    for pkg in $PACKAGES; do
        if ! command -v $pkg &> /dev/null; then MISSING="$MISSING $pkg"; fi
    done
    if [ ! -z "$MISSING" ]; then
        echo -e "${YELLOW}[НАСТРОЙКА] Установка пакетов: $MISSING${NC}"
        apt-get update -qq 2>&1 | grep -v "^[WE]:"
        apt-get install -y -qq $MISSING 2>&1 | grep -v "^[WE]:"
        echo -e "${GREEN}[НАСТРОЙКА] Готово${NC}"
        # Создаем флаг что пакеты установлены
        touch /tmp/vps-top-deps-installed
        sleep 1
    else
        # Если все пакеты уже есть, создаем флаг
        touch /tmp/vps-top-deps-installed
    fi
}

print_system_info() {
    print_header "Система"
    HOSTNAME=$(hostname)
    OS_INFO=$(get_os_info)
    ARCH=$(uname -m)
    KERNEL=$(uname -r)
    RESULTS[hostname]="$HOSTNAME"
    RESULTS[os]="$OS_INFO"
    RESULTS[arch]="$ARCH"
    RESULTS[kernel]="$KERNEL"
    print_result "Имя хоста" "$HOSTNAME"
    print_result "ОС" "$OS_INFO"
    get_isp_info
    RESULTS[isp_org]="$ISP_ORG"
    RESULTS[isp_location]="$ISP_LOCATION"
    print_result "Организация" "$ISP_ORG"
    print_result "Местоположение" "$ISP_LOCATION"
}

test_cpu() {
    print_header "CPU"
    CPU_MODEL=$(lscpu | grep "Model name" | cut -d':' -f2 | xargs)
    CPU_CORES=$(nproc)
    RESULTS[cpu_model]="$CPU_MODEL"
    RESULTS[cpu_cores]="$CPU_CORES"
    
    CPU_MHZ=$(lscpu | grep "CPU MHz" | awk '{print $3}')
    CPU_MAX_MHZ=$(lscpu | grep "CPU max MHz" | awk '{print $4}')
    if [ ! -z "$CPU_MAX_MHZ" ] && [ "$CPU_MAX_MHZ" != "0.0000" ]; then CPU_FREQ_NUM=$CPU_MAX_MHZ
    elif [ ! -z "$CPU_MHZ" ] && [ "$CPU_MHZ" != "0.0000" ]; then CPU_FREQ_NUM=$CPU_MHZ
    else CPU_FREQ_NUM=$(grep "cpu MHz" /proc/cpuinfo | head -1 | awk '{print $4}'); fi
    
    if [ ! -z "$CPU_FREQ_NUM" ] && [ "$CPU_FREQ_NUM" != "0.0000" ]; then
        CPU_FREQ=$(format_number "$CPU_FREQ_NUM" " МГц")
        RESULTS[cpu_freq_mhz]="$CPU_FREQ_NUM"
    else
        CPU_FREQ="N/A"
        RESULTS[cpu_freq_mhz]="0"
    fi
    
    VIRT=$(systemd-detect-virt 2>/dev/null)
    if [ "$VIRT" = "none" ] || [ "$VIRT" = "unknown" ]; then IS_VIRTUALIZED=0; VIRT="dedic"; fi
    RESULTS[virtualization]="$VIRT"
    
    print_result "Название" "$CPU_MODEL"
    print_result "Ядра" "$CPU_CORES"
    
    if [ "$CPU_FREQ" != "N/A" ] && [ ! -z "$CPU_FREQ_NUM" ] && [ "$CPU_FREQ_NUM" != "0.0000" ]; then
        if (( $(echo "$CPU_FREQ_NUM < 3100" | bc -l 2>/dev/null) )); then print_error "Частота" "$CPU_FREQ"
        elif (( $(echo "$CPU_FREQ_NUM < 4300" | bc -l 2>/dev/null) )); then print_warn "Частота" "$CPU_FREQ"
        else print_result_colored "Частота" "$CPU_FREQ"; fi
    fi
    print_result "Виртуализация" "$VIRT"
    
    SINGLE=$(sysbench cpu --cpu-max-prime=20000 --threads=1 --time=5 run 2>/dev/null | grep "events per second" | awk '{print $4}')
    SINGLE_FMT=$(format_number "$SINGLE" "")
    RESULTS[cpu_single_thread]="$SINGLE"
    if [ ! -z "$SINGLE" ]; then
        if (( $(echo "$SINGLE < 1000" | bc -l 2>/dev/null) )); then print_error "Sysbench 20k (1 поток)" "${SINGLE_FMT} событий/сек"
        elif (( $(echo "$SINGLE < 1500" | bc -l 2>/dev/null) )); then print_warn "Sysbench 20k (1 поток)" "${SINGLE_FMT} событий/сек"
        else print_result_colored "Sysbench 20k (1 поток)" "${SINGLE_FMT} событий/сек"; fi
    else print_result "1 поток" "${SINGLE_FMT} событий/сек"; fi
    
    if command -v 7z &> /dev/null; then
        SEVENZ_RESULT=$(7z b -mmt1 2>/dev/null | grep "Tot:" | awk '{print $4}')
        if [ ! -z "$SEVENZ_RESULT" ]; then
            SEVENZ_FMT=$(format_number "$SEVENZ_RESULT" " MIPS")
            SEVENZ_NUM=$(echo "$SEVENZ_RESULT" | tr -d ' ')
            RESULTS[cpu_7zip_mips]="$SEVENZ_NUM"
if (( $(echo "$SEVENZ_NUM < 3000" | bc -l 2>/dev/null) )); then print_error "7-Zip (1 поток)" "$SEVENZ_FMT"
        elif (( $(echo "$SEVENZ_NUM < 4500" | bc -l 2>/dev/null) )); then print_warn "7-Zip (1 поток)" "$SEVENZ_FMT"
        else print_result_colored "7-Zip (1 поток)" "$SEVENZ_FMT"; fi
        fi
    fi
    
    OPENSSL_OUTPUT=$(openssl speed rsa2048 2>&1)
    OPENSSL_RSA=$(echo "$OPENSSL_OUTPUT" | grep "rsa 2048" | awk '{print $6}')
    if [ ! -z "$OPENSSL_RSA" ] && [ "$OPENSSL_RSA" != "0.0" ]; then
        OPENSSL_FMT=$(format_number "$OPENSSL_RSA" " подписей/сек")
        OPENSSL_NUM=$(echo "$OPENSSL_RSA" | tr -d ' ')
        RESULTS[cpu_openssl_rsa]="$OPENSSL_NUM"
        if (( $(echo "$OPENSSL_NUM < 2000" | bc -l 2>/dev/null) )); then print_error "OpenSSL RSA-2048" "$OPENSSL_FMT"
        elif (( $(echo "$OPENSSL_NUM < 3500" | bc -l 2>/dev/null) )); then print_warn "OpenSSL RSA-2048" "$OPENSSL_FMT"
        else print_result_colored "OpenSSL RSA-2048" "$OPENSSL_FMT"; fi
    else print_warn "OpenSSL RSA-2048" "тест не завершен"; fi
    
    RESULTS[cpu_steal_percent]="0"
    if [ $IS_VIRTUALIZED -eq 1 ]; then
        if command -v mpstat &> /dev/null; then
            MPSTAT_OUTPUT=$(mpstat 1 3 2>/dev/null)
            STEAL=$(echo "$MPSTAT_OUTPUT" | grep -i average | awk '{for(i=1;i<=NF;i++) if($i ~ /[0-9]+\.[0-9]+/ && $(i-1) ~ /steal/) print $i}')
            if [ -z "$STEAL" ]; then STEAL=$(echo "$MPSTAT_OUTPUT" | grep -i average | awk '{print $11}'); fi
            if [ ! -z "$STEAL" ] && [ "$STEAL" != "" ] && [[ "$STEAL" =~ ^[0-9]+\.?[0-9]*$ ]]; then
                STEAL_FMT=$(format_number "$STEAL" "%")
                RESULTS[cpu_steal_percent]="$STEAL"
                if (( $(echo "$STEAL > 5.0" | bc -l 2>/dev/null) )); then print_error "CPU Steal" "${STEAL_FMT} (перепродажа!)"
                elif (( $(echo "$STEAL > 2.0" | bc -l 2>/dev/null) )); then print_warn "CPU Steal" "${STEAL_FMT}"
                else print_result_colored "CPU Steal" "${STEAL_FMT}"; fi
            fi
        fi
    fi
}

test_memory() {
    print_header "Память"
    TOTAL=$(free -h | grep Mem | awk '{print $2}')
    AVAIL=$(free -h | grep Mem | awk '{print $7}')
    TOTAL_MB=$(free -m | grep Mem | awk '{print $2}')
    RESULTS[ram_total_mb]="$TOTAL_MB"
    print_result "Всего" "$TOTAL (свободно: $AVAIL)"
    
    READ_RESULT=$(sysbench memory --memory-block-size=1M --memory-total-size=2G --memory-oper=read --threads=1 run 2>/dev/null | grep "transferred")
    READ_SPEED_RAW=$(echo "$READ_RESULT" | sed -n 's/.*(\(.*\))/\1/p')
    READ_SPEED_NUM=$(echo "$READ_SPEED_RAW" | awk '{print $1}')
    READ_SPEED=$(format_number "$READ_SPEED_NUM" " МиБ/сек")
    RESULTS[ram_read_speed]="$READ_SPEED_NUM"
    
    if [ ! -z "$READ_SPEED_NUM" ]; then
        if (( $(echo "$READ_SPEED_NUM < 30000" | bc -l 2>/dev/null) )); then print_error "Скорость чтения" "$READ_SPEED"
        elif (( $(echo "$READ_SPEED_NUM < 50000" | bc -l 2>/dev/null) )); then print_warn "Скорость чтения" "$READ_SPEED"
        else print_result_colored "Скорость чтения" "$READ_SPEED"; fi
    else print_result "Скорость чтения" "$READ_SPEED"; fi
}

test_disk() {
    print_header "Диски"
    DISK_SIZE=$(df -h / | tail -1 | awk '{print $2}')
    DISK_USED=$(df -h / | tail -1 | awk '{print $5}')
    DISK_SIZE_GB=$(df -BG / | tail -1 | awk '{print $2}' | sed 's/G//')
    RESULTS[disk_size_gb]="$DISK_SIZE_GB"
    print_result "Размер /" "$DISK_SIZE (использовано: $DISK_USED)"
    
    SEQ_RESULT=$(fio --name=seq --ioengine=libaio --iodepth=32 --rw=write --bs=1M --direct=1 --size=512M --numjobs=1 --runtime=10 --time_based --group_reporting --filename=/tmp/fio_seq 2>/dev/null)
    SEQ_WRITE=$(echo "$SEQ_RESULT" | grep "WRITE:" | grep -oP 'BW=\K[^,]+' | head -1)
    [ -z "$SEQ_WRITE" ] && SEQ_WRITE=$(echo "$SEQ_RESULT" | grep "bw=" | grep -oP 'bw=\K[^,]+' | head -1)
    
    if [ ! -z "$SEQ_WRITE" ]; then
        SEQ_NUM=$(echo "$SEQ_WRITE" | grep -oP '[0-9.]+' | head -1)
        if [[ "$SEQ_WRITE" == *"GiB"* ]]; then
            SEQ_NUM=$(echo "scale=0; $SEQ_NUM * 1024" | bc)
            SEQ_WRITE="${SEQ_NUM}MiB/s"
        fi
        RESULTS[disk_seq_write]="$SEQ_NUM"
        if [ ! -z "$SEQ_NUM" ]; then
            if (( $(echo "$SEQ_NUM < 1000" | bc -l 2>/dev/null) )); then print_error "Послед. запись" "$SEQ_WRITE"
            elif (( $(echo "$SEQ_NUM < 2500" | bc -l 2>/dev/null) )); then print_warn "Послед. запись" "$SEQ_WRITE"
            else print_result_colored "Послед. запись" "$SEQ_WRITE"; fi
        else print_result "Послед. запись" "$SEQ_WRITE"; fi
    else RESULTS[disk_seq_write]="0"; print_result "Послед. запись" "N/A"; fi
    
    RAND_READ_RESULT=$(fio --name=rand --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --direct=1 --size=256M --numjobs=4 --runtime=10 --time_based --group_reporting --filename=/tmp/fio_rand 2>/dev/null)
    RAND_READ_IOPS_RAW=$(echo "$RAND_READ_RESULT" | grep -E "read\s*:" | grep -oP 'IOPS=\K[0-9.]+[k]?' | head -1)
    [ -z "$RAND_READ_IOPS_RAW" ] && RAND_READ_IOPS_RAW=$(echo "$RAND_READ_RESULT" | grep "IOPS=" | grep -oP 'IOPS=\K[0-9.]+[k]?' | head -1)
    RAND_READ_IOPS=$(format_number "$RAND_READ_IOPS_RAW" " IOPS")
    
    if [ ! -z "$RAND_READ_IOPS_RAW" ]; then
        IOPS_NUM=$(echo "$RAND_READ_IOPS_RAW" | sed 's/k/*1000/' | bc 2>/dev/null)
        RESULTS[disk_rand_read_iops]="$IOPS_NUM"
        if [ ! -z "$IOPS_NUM" ]; then
            if (( $(echo "$IOPS_NUM < 75000" | bc -l 2>/dev/null) )); then print_error "Случ. чтение" "$RAND_READ_IOPS"
            elif (( $(echo "$IOPS_NUM < 150000" | bc -l 2>/dev/null) )); then print_warn "Случ. чтение" "$RAND_READ_IOPS"
            else print_result_colored "Случ. чтение" "$RAND_READ_IOPS"; fi
        else print_result "Случ. чтение" "$RAND_READ_IOPS"; fi
    else RESULTS[disk_rand_read_iops]="0"; print_result "Случ. чтение" "N/A"; fi
    
    RAND_WRITE_RESULT=$(fio --name=randw --ioengine=libaio --iodepth=32 --rw=randwrite --bs=4k --direct=1 --size=256M --numjobs=4 --runtime=10 --time_based --group_reporting --filename=/tmp/fio_randw 2>/dev/null)
    RAND_WRITE_IOPS_RAW=$(echo "$RAND_WRITE_RESULT" | grep -E "write\s*:" | grep -oP 'IOPS=\K[0-9.]+[k]?' | head -1)
    [ -z "$RAND_WRITE_IOPS_RAW" ] && RAND_WRITE_IOPS_RAW=$(echo "$RAND_WRITE_RESULT" | grep "IOPS=" | grep -oP 'IOPS=\K[0-9.]+[k]?' | head -1)
    RAND_WRITE_IOPS=$(format_number "$RAND_WRITE_IOPS_RAW" " IOPS")
    
    if [ ! -z "$RAND_WRITE_IOPS_RAW" ]; then
        IOPS_W_NUM=$(echo "$RAND_WRITE_IOPS_RAW" | sed 's/k/*1000/' | bc 2>/dev/null)
        RESULTS[disk_rand_write_iops]="$IOPS_W_NUM"
        if [ ! -z "$IOPS_W_NUM" ]; then
            if (( $(echo "$IOPS_W_NUM < 50000" | bc -l 2>/dev/null) )); then print_error "Случ. запись" "$RAND_WRITE_IOPS"
            elif (( $(echo "$IOPS_W_NUM < 100000" | bc -l 2>/dev/null) )); then print_warn "Случ. запись" "$RAND_WRITE_IOPS"
            else print_result_colored "Случ. запись" "$RAND_WRITE_IOPS"; fi
        else print_result "Случ. запись" "$RAND_WRITE_IOPS"; fi
    else RESULTS[disk_rand_write_iops]="0"; print_result "Случ. запись" "N/A"; fi
    
    if command -v ioping &> /dev/null; then
        IOPING_RESULT=$(ioping -c 10 -q /tmp 2>/dev/null)
        if [ $? -eq 0 ]; then
            LAT_LINE=$(echo "$IOPING_RESULT" | grep "min/avg/max")
            if [ ! -z "$LAT_LINE" ]; then
                LAT_VALUES=$(echo "$LAT_LINE" | sed 's/.*= //' | tr '/' ' ')
                read LAT_MIN_RAW LAT_MIN_UNIT LAT_AVG_RAW LAT_AVG_UNIT LAT_MAX_RAW LAT_MAX_UNIT LAT_MDEV_RAW LAT_MDEV_UNIT <<< "$LAT_VALUES"
                if [ "$LAT_AVG_UNIT" = "us" ]; then
                    LAT_AVG=$(echo "scale=2; $LAT_AVG_RAW / 1000" | bc 2>/dev/null)
                    LAT_MIN=$(echo "scale=2; $LAT_MIN_RAW / 1000" | bc 2>/dev/null)
                    LAT_MAX=$(echo "scale=2; $LAT_MAX_RAW / 1000" | bc 2>/dev/null)
                    LAT_UNIT="ms"
                elif [ "$LAT_AVG_UNIT" = "ms" ]; then
                    LAT_AVG=$LAT_AVG_RAW
                    LAT_MIN=$LAT_MIN_RAW
                    LAT_MAX=$LAT_MAX_RAW
                    LAT_UNIT="ms"
                else
                    LAT_AVG=$LAT_AVG_RAW
                    LAT_MIN=$LAT_MIN_RAW
                    LAT_MAX=$LAT_MAX_RAW
                    LAT_UNIT=$LAT_AVG_UNIT
                fi
                RESULTS[disk_latency_avg]="$LAT_AVG"
                RESULTS[disk_latency_min]="$LAT_MIN"
                RESULTS[disk_latency_max]="$LAT_MAX"
                if [ ! -z "$LAT_AVG" ] && [ "$LAT_AVG" != "" ]; then
                    if (( $(echo "$LAT_AVG < 1.0" | bc -l 2>/dev/null) )); then print_result_colored "Отклик" "${LAT_AVG} ${LAT_UNIT} (мин: ${LAT_MIN}, макс: ${LAT_MAX})"
                    elif (( $(echo "$LAT_AVG < 5.0" | bc -l 2>/dev/null) )); then print_warn "Отклик" "${LAT_AVG} ${LAT_UNIT} (мин: ${LAT_MIN}, макс: ${LAT_MAX})"
                    else print_error "Отклик" "${LAT_AVG} ${LAT_UNIT} (мин: ${LAT_MIN}, макс: ${LAT_MAX})"; fi
                fi
            fi
        fi
    fi
    rm -f /tmp/fio_* /tmp/test_lat
}

test_network_ping() {
    print_header "Сеть - пинг"
    declare -A HOSTS=( ["1.1.1.1"]="Cloudflare" ["google.com"]="Google" ["ya.ru"]="Yandex" ["sfr.fr"]="France" ["ps.kz"]="Kazakhstan" ["78.186.60.77"]="Turkey" ["85.172.106.217"]="Krasnodar" ["193.58.251.251"]="Yekaterinburg" )
    for host in "${!HOSTS[@]}"; do
        PING_FULL=$(ping -c 3 -W 2 $host 2>/dev/null)
        if [ $? -eq 0 ]; then
            PING_STATS=$(echo "$PING_FULL" | tail -1)
            AVG_RAW=$(echo $PING_STATS | awk -F'/' '{print $5}')
            AVG=$(format_number "$AVG_RAW" "ms")
            JITTER_RAW=$(echo $PING_STATS | awk -F'/' '{print $7}' | sed 's/[^0-9.]//g')
            LOSS=$(echo "$PING_FULL" | grep "packet loss" | awk '{print $6}')
            SAFE_HOST=$(echo "$host" | sed 's/\./_/g')
            RESULTS["ping_${SAFE_HOST}_avg"]="$AVG_RAW"
            RESULTS["ping_${SAFE_HOST}_jitter"]="$JITTER_RAW"
            RESULTS["ping_${SAFE_HOST}_loss"]="$LOSS"
            if [ ! -z "$JITTER_RAW" ] && [ "$JITTER_RAW" != "" ]; then JITTER=$(format_number "$JITTER_RAW" "ms"); else JITTER="N/A"; fi
            if [ "$LOSS" = "0%" ]; then
                if [ ! -z "$AVG_RAW" ] && [ "$AVG_RAW" != "" ]; then
                    if (( $(echo "$AVG_RAW < 30.0" | bc -l 2>/dev/null) )); then print_result_colored "${HOSTS[$host]}" "$AVG ±${JITTER}, потерь: $LOSS"
                    elif (( $(echo "$AVG_RAW < 80.0" | bc -l 2>/dev/null) )); then print_warn "${HOSTS[$host]}" "$AVG ±${JITTER}, потерь: $LOSS"
                    else print_error "${HOSTS[$host]}" "$AVG ±${JITTER}, потерь: $LOSS"; fi
                else print_result "${HOSTS[$host]}" "$AVG ±${JITTER}, потерь: $LOSS"; fi
            else print_error "${HOSTS[$host]}" "$AVG ±${JITTER}, потерь: $LOSS"; fi
        else print_error "${HOSTS[$host]}" "недоступен"; fi
    done
    DEFAULT_IFACE=$(ip route | grep default | awk '{print $5}' | head -1)
    if [ ! -z "$DEFAULT_IFACE" ]; then
        MTU=$(ip link show $DEFAULT_IFACE | grep mtu | awk '{print $5}')
        RESULTS[network_mtu]="$MTU"
        if [ ! -z "$MTU" ]; then
            if [ "$MTU" -eq 1500 ]; then print_result "MTU ($DEFAULT_IFACE)" "$MTU (стандартный)"
            elif [ "$MTU" -gt 1500 ]; then print_result "MTU ($DEFAULT_IFACE)" "$MTU (jumbo frames)"
            else print_warn "MTU ($DEFAULT_IFACE)" "$MTU (заниженный)"; fi
        fi
    fi
}

test_network_speed() {
    print_header "Сеть - Скорость"
    BEST_SPEED=0
    SPEED1=$(timeout 60 curl -o /dev/null -w "%{speed_download}" -s http://cachefly.cachefly.net/300mb.test 2>/dev/null)
    if [ ! -z "$SPEED1" ] && [ "$SPEED1" != "0" ] && [ "$SPEED1" != "0.000" ]; then
        SPEED1_MBPS=$(echo "scale=1; $SPEED1 / 1024 / 1024 * 8" | bc 2>/dev/null)
        if [ ! -z "$SPEED1_MBPS" ]; then print_result "300МБ тест" "${SPEED1_MBPS} Мбит/с"; BEST_SPEED=$SPEED1_MBPS; fi
    else print_warn "300МБ тест" "не завершен"; fi
    
    SPEED2=$(timeout 60 curl -o /dev/null -w "%{speed_download}" -s http://cachefly.cachefly.net/100mb.test 2>/dev/null)
    if [ ! -z "$SPEED2" ] && [ "$SPEED2" != "0" ] && [ "$SPEED2" != "0.000" ]; then
        SPEED2_MBPS=$(echo "scale=1; $SPEED2 / 1024 / 1024 * 8" | bc 2>/dev/null)
        if [ ! -z "$SPEED2_MBPS" ]; then
            print_result "100МБ тест" "${SPEED2_MBPS} Мбит/с"
            if (( $(echo "$SPEED2_MBPS > $BEST_SPEED" | bc -l 2>/dev/null) )); then BEST_SPEED=$SPEED2_MBPS; fi
        fi
    else print_warn "100MB тест" "не завершен"; fi
    
    if (( $(echo "$BEST_SPEED == 0" | bc -l 2>/dev/null) )); then
        SPEED3=$(timeout 60 curl -o /dev/null -w "%{speed_download}" -s -L https://github.com/git/git/archive/refs/tags/v2.43.0.tar.gz 2>/dev/null)
        if [ ! -z "$SPEED3" ] && [ "$SPEED3" != "0" ] && [ "$SPEED3" != "0.000" ]; then
            SPEED3_MBPS=$(echo "scale=1; $SPEED3 / 1024 / 1024 * 8" | bc 2>/dev/null)
            if [ ! -z "$SPEED3_MBPS" ]; then print_result "GitHub CDN" "${SPEED3_MBPS} Мбит/с"; BEST_SPEED=$SPEED3_MBPS; fi
        fi
    fi
    
    RESULTS[network_speed_mbps]="$BEST_SPEED"
    if [ ! -z "$BEST_SPEED" ] && (( $(echo "$BEST_SPEED > 0" | bc -l 2>/dev/null) )); then
        if (( $(echo "$BEST_SPEED < 200" | bc -l 2>/dev/null) )); then print_error "Скорость канала" "${BEST_SPEED} Мбит/с (очень низкая)"
        elif (( $(echo "$BEST_SPEED < 700" | bc -l 2>/dev/null) )); then print_warn "Скорость канала" "${BEST_SPEED} Мбит/с (низкая)"; fi
    fi
}

generate_json_report() {
    local timestamp=$(date +%s)
    RESULTS[timestamp]="$timestamp"
    RESULTS[test_date]=$(date '+%Y-%m-%d %H:%M:%S')
    RESULTS[issues_count]="$ISSUES"
    REPORT_ID=$(echo -n "${RESULTS[hostname]}_$(date +%s%N)_$RANDOM" | md5sum | cut -d' ' -f1 | cut -c1-16)
    RESULTS[report_id]="$REPORT_ID"
    
    escape_json() {
        local str="$1"
        str="${str//\\/\\\\}"
        str="${str//\"/\\\"}"
        str="${str//$'\n'/}"
        str="${str//$'\t'/ }"
        echo "$str"
    }
    
    get_num() {
        local val="${1:-0}"
        if [[ "$val" =~ ^[0-9]+\.?[0-9]*$ ]] && [ "$val" != "" ]; then
            echo "$val"
        else
            echo "0"
        fi
    }
    
    local json="{"
    json="${json}\"report_id\":\"${RESULTS[report_id]}\","
    json="${json}\"timestamp\":${RESULTS[timestamp]},"
    json="${json}\"test_date\":\"${RESULTS[test_date]}\","
    json="${json}\"issues_count\":${RESULTS[issues_count]},"
    
    json="${json}\"system\":{"
    json="${json}\"hostname\":\"$(escape_json "${RESULTS[hostname]}")\","
    json="${json}\"os\":\"$(escape_json "${RESULTS[os]}")\","
    json="${json}\"arch\":\"$(escape_json "${RESULTS[arch]}")\","
    json="${json}\"kernel\":\"$(escape_json "${RESULTS[kernel]}")\","
    json="${json}\"isp_org\":\"$(escape_json "${RESULTS[isp_org]}")\","
    json="${json}\"isp_location\":\"$(escape_json "${RESULTS[isp_location]}")\""
    json="${json}},"
    
    json="${json}\"cpu\":{"
    json="${json}\"model\":\"$(escape_json "${RESULTS[cpu_model]}")\","
    json="${json}\"cores\":$(get_num "${RESULTS[cpu_cores]}"),"
    json="${json}\"freq_mhz\":$(get_num "${RESULTS[cpu_freq_mhz]}"),"
    json="${json}\"virtualization\":\"$(escape_json "${RESULTS[virtualization]}")\","
    json="${json}\"single_thread\":$(get_num "${RESULTS[cpu_single_thread]}"),"
    json="${json}\"7zip_mips\":$(get_num "${RESULTS[cpu_7zip_mips]}"),"
    json="${json}\"openssl_rsa\":$(get_num "${RESULTS[cpu_openssl_rsa]}"),"
    json="${json}\"steal_percent\":$(get_num "${RESULTS[cpu_steal_percent]}")"
    json="${json}},"
    
    json="${json}\"ram\":{"
    json="${json}\"total_mb\":$(get_num "${RESULTS[ram_total_mb]}"),"
    json="${json}\"read_speed\":$(get_num "${RESULTS[ram_read_speed]}")"
    json="${json}},"
    
    json="${json}\"disk\":{"
    json="${json}\"size_gb\":$(get_num "${RESULTS[disk_size_gb]}"),"
    json="${json}\"seq_write\":$(get_num "${RESULTS[disk_seq_write]}"),"
    json="${json}\"rand_read_iops\":$(get_num "${RESULTS[disk_rand_read_iops]}"),"
    json="${json}\"rand_write_iops\":$(get_num "${RESULTS[disk_rand_write_iops]}"),"
    json="${json}\"latency_avg\":$(get_num "${RESULTS[disk_latency_avg]}"),"
    json="${json}\"latency_min\":$(get_num "${RESULTS[disk_latency_min]}"),"
    json="${json}\"latency_max\":$(get_num "${RESULTS[disk_latency_max]}")"
    json="${json}},"
    
    json="${json}\"network\":{"
    json="${json}\"speed_mbps\":$(get_num "${RESULTS[network_speed_mbps]}"),"
    json="${json}\"mtu\":$(get_num "${RESULTS[network_mtu]}"),"
    json="${json}\"ping\":{"
    
    local first_ping=1
    for key in "${!RESULTS[@]}"; do
        if [[ $key == ping_* ]]; then
            if [ $first_ping -eq 0 ]; then json="${json},"; fi
            local value="${RESULTS[$key]}"
            
            if [[ $value =~ ^[0-9]+\.?[0-9]*$ ]]; then
                json="${json}\"${key}\":$(get_num "$value")"
            elif [[ $value =~ ^[0-9]+\.?[0-9]*%$ ]]; then
                json="${json}\"${key}\":\"$(escape_json "$value")\""
            elif [ -z "$value" ] || [ "$value" = "N/A" ]; then
                json="${json}\"${key}\":\"N/A\""
            else
                json="${json}\"${key}\":\"$(escape_json "$value")\""
            fi
            first_ping=0
        fi
    done
    
    json="${json}}}"
    json="${json}}"
    
    echo "$json"
}

save_report_local() {
    local report_filename="vps-top-report-$(date +%Y%m%d-%H%M%S)-${RANDOM}.txt"
    {
        echo "====================================="
        echo "Отчет производительности VPS"
        echo "Создан: $(date '+%Y-%m-%d %H:%M:%S')"
        echo "ID отчета: ${RESULTS[report_id]}"
        echo "====================================="
        echo ""
        for key in "${!RESULTS[@]}"; do echo "$key: ${RESULTS[$key]}"; done
        echo ""
        echo "Найдено проблем: $ISSUES"
    } > "$report_filename"
    echo -e "${GREEN}✓ Отчет сохранен локально: $report_filename${NC}"
}

send_report_to_server() {
    local json_data=$(generate_json_report)
    
    echo -e "${CYAN}Отправка отчета на сервер...${NC}"
    
    local response=$(curl -s -w "\n%{http_code}" \
        -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $REPORT_TOKEN" \
        --connect-timeout 10 \
        --max-time 30 \
        -d "$json_data" \
        "$REPORT_SERVER" 2>/dev/null)
    
    local http_code=$(echo "$response" | tail -n1)
    local body=$(echo "$response" | head -n-1)
    
    if [ "$http_code" = "200" ] || [ "$http_code" = "201" ]; then
        echo -e "${GREEN}✓ Отчет успешно отправлен на сервер${NC}"
        
        local report_url=""
        if command -v python3 &> /dev/null; then
            report_url=$(echo "$body" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('url', ''))" 2>/dev/null)
        fi
        
        if [ -z "$report_url" ]; then
            report_url=$(echo "$body" | grep -oP '"url"\s*:\s*"\K[^"]+' 2>/dev/null)
        fi
        
        if [ ! -z "$report_url" ]; then
            echo -e "${CYAN}Ссылка на отчет: ${report_url}${NC}"
        fi
        
        return 0
    else
        echo -e "${RED}✗ Ошибка отправки (HTTP $http_code)${NC}"
        if [ ! -z "$body" ]; then
            echo -e "${RED}Ответ сервера: $body${NC}"
        fi
        return 1
    fi
}

main() {
    check_dependencies
    clear
    echo -e "${GREEN}╔════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║  VPS-TOP.ru > Performance Check v.4    ║${NC}"
    echo -e "${GREEN}║  $(date '+%Y-%m-%d %H:%M:%S')                   ║${NC}"
    echo -e "${GREEN}╚════════════════════════════════════════╝${NC}"
    START_TIME=$(date +%s)
    print_system_info
    test_cpu
    test_memory
    test_disk
    test_network_ping
    test_network_speed
    END_TIME=$(date +%s)
    DURATION=$((END_TIME - START_TIME))
    echo ""
    echo -e "${CYAN}Время выполнения: ${DURATION} сек${NC}"
    echo ""
    
    if [ -t 0 ]; then
        echo -e "${YELLOW}Сохранить отчет локально?${NC} [Д/н]: "
        read -r save_local
        save_local=${save_local:-Д}
        if [[ "$save_local" =~ ^[ДдYy]$ ]]; then save_report_local; echo ""; fi
        
        echo -e "${YELLOW}Отправить анонимно на сервер?${NC} [Д/н]: "
        read -r send_remote
        send_remote=${send_remote:-Д}
        if [[ "$send_remote" =~ ^[ДдYy]$ ]]; then send_report_to_server; fi
    else
        echo -e "${YELLOW}[АВТО] Режим автозапуска активирован.${NC}"
        save_report_local
        echo ""
        send_report_to_server
    fi
    echo ""
}

main