#!/usr/bin/env bash

#
# Linux BenchTools - Script de Test Complet
# Version: 1.0.0
#
# Ce script collecte les informations hardware et exécute les benchmarks
# Génère un fichier result.json dans le dossier courant
#

set -e

# Couleurs pour l'affichage
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Variables globales
SCRIPT_VERSION="1.0.0"
OUTPUT_FILE="result.json"
TOTAL_STEPS=8
CURRENT_STEP=0

# Forcer locale en anglais pour parsing
export LC_ALL=C

# Ajouter /usr/sbin au PATH pour accéder à dmidecode, smartctl, ethtool
export PATH="/usr/sbin:/sbin:$PATH"

# Fonctions d'affichage
log_step() {
    CURRENT_STEP=$((CURRENT_STEP + 1))
    echo -e "${BLUE}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${GREEN}$1${NC}"
}

log_info() {
    echo -e "  ${GREEN}✓${NC} $1"
}

log_warn() {
    echo -e "  ${YELLOW}⚠${NC} $1"
}

log_error() {
    echo -e "  ${RED}✗${NC} $1"
}
safe_bc() {
    local expr="$1"
    # Renvoie 0 si bc plante, au lieu de laisser une chaîne vide
    local out
    out=$(echo "$expr" | bc 2>/dev/null) || out="0"
    echo "$out"
}
# Vérifier les permissions sudo
check_sudo() {
    echo -e "${YELLOW}════════════════════════════════════════════════════════${NC}"
    echo -e "${YELLOW}  Linux BenchTools - Script de Test${NC}"
    echo -e "${YELLOW}  Version ${SCRIPT_VERSION}${NC}"
    echo -e "${YELLOW}════════════════════════════════════════════════════════${NC}"
    echo ""
    echo -e "${BLUE}Ce script nécessite les permissions sudo pour :${NC}"
    echo "  - dmidecode (infos RAM, carte mère, BIOS)"
    echo "  - smartctl (infos disques)"
    echo "  - ethtool (vitesse réseau)"
    echo ""

    if ! sudo -v; then
        log_error "Permissions sudo requises. Veuillez relancer avec sudo."
        exit 1
    fi

    # Garder sudo actif pendant toute la durée du script
    while true; do sudo -n true; sleep 50; kill -0 "$$" || exit; done 2>/dev/null &

    log_info "Permissions sudo OK"
    echo ""
}

# Vérifier et installer les dépendances
check_dependencies() {
    local missing_essential=()
    local missing_bench=()
    local missing_optional=()

    echo -e "${BLUE}Vérification des dépendances...${NC}"

    # Outils essentiels
    for tool in curl jq lscpu free lsblk ip bc; do
        if ! command -v $tool &> /dev/null; then
            missing_essential+=($tool)
        fi
    done

    # Outils de benchmark
    for tool in sysbench fio iperf3; do
        if ! command -v $tool &> /dev/null; then
            missing_bench+=($tool)
        fi
    done

    # Outils optionnels (mais recommandés)
    for tool in dmidecode smartctl ethtool lspci; do
        if ! command -v $tool &> /dev/null; then
            missing_optional+=($tool)
        fi
    done

    # Installer les paquets manquants
    local to_install=()

    # Mapper les commandes vers les paquets Debian/Ubuntu
    declare -A package_map=(
        [curl]="curl"
        [jq]="jq"
        [lscpu]="util-linux"
        [free]="procps"
        [lsblk]="util-linux"
        [ip]="iproute2"
        [bc]="bc"
        [sysbench]="sysbench"
        [fio]="fio"
        [iperf3]="iperf3"
        [dmidecode]="dmidecode"
        [smartctl]="smartmontools"
        [ethtool]="ethtool"
        [lspci]="pciutils"
    )

    # Collecter tous les paquets à installer
    for tool in "${missing_essential[@]}" "${missing_bench[@]}" "${missing_optional[@]}"; do
        local package="${package_map[$tool]}"
        if [[ -n "$package" ]] && [[ ! " ${to_install[@]} " =~ " ${package} " ]]; then
            to_install+=($package)
        fi
    done

    # Installer si nécessaire
    if [[ ${#to_install[@]} -gt 0 ]]; then
        echo ""
        log_warn "Paquets manquants détectés : ${to_install[*]}"
        echo -e "${BLUE}Installation automatique des dépendances...${NC}"
        echo ""

        # Mettre à jour la liste des paquets
        echo "► Mise à jour de la liste des paquets..."
        if ! sudo apt-get update -qq 2>&1 | grep -v "Policy will reject signature"; then
            log_warn "Avertissement lors de apt-get update (continuer quand même)"
        fi
        echo "  Liste mise à jour"

        # Installer les paquets (avec sortie pour voir les erreurs)
        echo "► Installation de : ${to_install[*]}"
        local install_output
        install_output=$(sudo apt-get install -y "${to_install[@]}" 2>&1)
        local install_code=$?

        # Afficher la sortie (sans les warnings de signature)
        echo "$install_output" | grep -v "Policy will reject signature" || true

        if [[ $install_code -eq 0 ]]; then
            log_info "Installation terminée avec succès"

            # Forcer le shell à recharger le PATH pour voir les nouvelles commandes
            echo "► Rechargement du PATH..."
            hash -r

            # Vérifier que les commandes sont maintenant disponibles
            echo "► Vérification post-installation..."
            for tool in dmidecode smartctl ethtool; do
                if command -v $tool &> /dev/null; then
                    echo "  ✓ $tool : $(which $tool)"
                else
                    echo "  ✗ $tool : NON TROUVÉ après installation"
                fi
            done
        else
            log_error "Erreur lors de l'installation (code: $install_code)"
            echo "Veuillez installer manuellement : sudo apt-get install ${to_install[*]}"
            exit 1
        fi

        echo ""
    else
        log_info "Toutes les dépendances sont déjà installées"
    fi
}

#
# ÉTAPE 1 : Collecte informations système de base
#
collect_system_info() {
    log_step "Collecte des informations système de base"

    local hostname=$(hostname)
    local os_name=$(grep '^ID=' /etc/os-release | cut -d= -f2 | tr -d '"')
    local os_version=$(grep '^VERSION=' /etc/os-release | cut -d= -f2 | tr -d '"')
    local kernel=$(uname -r)
    local arch=$(uname -m)

    SYSTEM_INFO=$(jq -n \
        --arg hostname "$hostname" \
        --arg os_name "$os_name" \
        --arg os_version "$os_version" \
        --arg kernel "$kernel" \
        --arg arch "$arch" \
        '{
            hostname: $hostname,
            os: {
                name: $os_name,
                version: $os_version,
                kernel_version: $kernel,
                architecture: $arch
            }
        }')

    log_info "Hostname: $hostname"
    log_info "OS: $os_name $os_version"
    log_info "Kernel: $kernel"
}

#
# ÉTAPE 2 : Collecte informations CPU
#
collect_cpu_info() {
    log_step "Collecte des informations CPU"

    local vendor=$(lscpu | grep 'Vendor ID' | awk '{print $3}')
    local model=$(lscpu | sed -n 's/^Model name:[ \t]*//p' | xargs)
    local cores=$(lscpu | awk '/^CPU\(s\):/ {print $2}')
    local threads=$(nproc)

    # Fréquences
    local cpu_mhz=$(lscpu | grep 'CPU MHz:' | awk '{print $3}')
    local cpu_max_mhz=$(lscpu | grep 'CPU max MHz:' | awk '{print $4}')
    local cpu_min_mhz=$(lscpu | grep 'CPU min MHz:' | awk '{print $4}')

    # Convertir en GHz
    local base_freq_ghz="null"
    local max_freq_ghz="null"
    if [[ -n "$cpu_mhz" ]]; then
        base_freq_ghz=$(echo "scale=2; $cpu_mhz / 1000" | bc)
    fi
    if [[ -n "$cpu_max_mhz" ]]; then
        max_freq_ghz=$(echo "scale=2; $cpu_max_mhz / 1000" | bc)
    fi

    # Caches
    local cache_l1d=$(lscpu | grep 'L1d cache:' | awk '{print $3}' | sed 's/K//' | sed 's/M/*1024/' | bc 2>/dev/null || echo "null")
    local cache_l1i=$(lscpu | grep 'L1i cache:' | awk '{print $3}' | sed 's/K//' | sed 's/M/*1024/' | bc 2>/dev/null || echo "null")
    local cache_l2=$(lscpu | grep 'L2 cache:' | awk '{print $3}' | sed 's/K//' | sed 's/M/*1024/' | bc 2>/dev/null || echo "null")
    local cache_l3=$(lscpu | grep 'L3 cache:' | awk '{print $3}' | sed 's/K//' | sed 's/M/*1024/' | bc 2>/dev/null || echo "null")

    # Calculer L1 total
    local cache_l1_kb="null"
    if [[ "$cache_l1d" != "null" && "$cache_l1i" != "null" ]]; then
        cache_l1_kb=$(echo "$cache_l1d + $cache_l1i" | bc)
    fi

    # Flags CPU (limiter aux plus importants)
    local flags=$(lscpu | grep 'Flags:' | sed 's/Flags:[ \t]*//')
    local important_flags="avx,avx2,sse4_1,sse4_2,aes,vt-x,vmx,svm"
    local flags_array="[]"
    if [[ -n "$flags" ]]; then
        flags_array=$(echo "$flags" | tr ' ' '\n' | grep -E "^(avx|avx2|sse4_1|sse4_2|aes|pclmulqdq|sha|rdrand|rdseed|popcnt)$" | jq -R . | jq -s .)
    fi

    CPU_INFO=$(jq -n \
        --arg vendor "$vendor" \
        --arg model "$model" \
        --argjson cores "${cores:-0}" \
        --argjson threads "${threads:-0}" \
        --argjson base_freq "$base_freq_ghz" \
        --argjson max_freq "$max_freq_ghz" \
        --argjson l1 "${cache_l1_kb:-null}" \
        --argjson l2 "${cache_l2:-null}" \
        --argjson l3 "${cache_l3:-null}" \
        --argjson flags "$flags_array" \
        '{
            vendor: $vendor,
            model: $model,
            cores: $cores,
            threads: $threads,
            base_freq_ghz: $base_freq,
            max_freq_ghz: $max_freq,
            cache_l1_kb: $l1,
            cache_l2_kb: $l2,
            cache_l3_kb: $l3,
            flags: $flags
        }')

    log_info "CPU: $model"
    log_info "Cores: $cores, Threads: $threads"
    log_info "Freq: ${base_freq_ghz}GHz - ${max_freq_ghz}GHz"
}

#
# ÉTAPE 3 : Collecte informations RAM
#
collect_ram_info() {
    log_step "Collecte des informations RAM"

    # Statistiques RAM de l'OS (total, used, free, shared)
    local mem_line=$(free -m | grep '^Mem:')
    local total_mb=$(echo "$mem_line" | awk '{print $2}')
    local used_mb=$(echo "$mem_line" | awk '{print $3}')
    local free_mb=$(echo "$mem_line" | awk '{print $4}')
    local shared_mb=$(echo "$mem_line" | awk '{print $5}')  # RAM partagée (inclut tmpfs, vidéo partagée, etc.)

    # Infos détaillées avec dmidecode (nécessite sudo)
    local slots_total="null"
    local slots_used="null"
    local ecc="null"
    local layout="[]"

    # dmidecode nécessite sudo pour fonctionner
    echo "  [DEBUG] Vérification dmidecode..."
    if command -v dmidecode &> /dev/null; then
        echo "  [DEBUG] dmidecode trouvé: $(which dmidecode)"
        # Nombre de slots
        echo "  [DEBUG] Exécution: sudo dmidecode -t 16..."
        slots_total=$(sudo dmidecode -t 16 2>/dev/null | grep 'Number Of Devices' | awk '{print $4}' | head -1)
        echo "  [DEBUG] Slots total: $slots_total"

        # ECC
        if sudo dmidecode -t 16 2>/dev/null | grep 'Error Correction Type' | grep -q 'None'; then
            ecc="false"
        else
            ecc="true"
        fi

        # Layout des barrettes (parsing complexe)
        local dimm_data=$(sudo dmidecode -t 17 | grep -E 'Locator:|Size:|Type:|Speed:|Manufacturer:' | \
            awk '
                /Locator:/ && !/Bank/ { slot=$2; gsub(/_/, "", slot) }
                /Size:/ && /[0-9]+ [GM]B/ {
                    size=$2;
                    if ($3 == "GB") size=size*1024;
                    if ($3 == "MB") size=size;
                }
                /Type:/ && !/Detail/ { type=$2 }
                /Speed:/ && /[0-9]+ MT/ { speed=$2 }
                /Manufacturer:/ {
                    manu=$2;
                    if (size > 0) {
                        print slot "," size "," type "," speed "," manu;
                    }
                    slot=""; size=0; type=""; speed=""; manu="";
                }
            ')

        # Convertir en JSON
        if [[ -n "$dimm_data" ]]; then
            layout=$(echo "$dimm_data" | while IFS=',' read -r slot size type speed manu; do
                jq -n \
                    --arg slot "$slot" \
                    --argjson size "$size" \
                    --arg type "$type" \
                    --argjson speed "$speed" \
                    --arg manu "$manu" \
                    '{slot: $slot, size_mb: $size, type: $type, speed_mhz: $speed, manufacturer: $manu}'
            done | jq -s .)

            slots_used=$(echo "$layout" | jq 'length')
        fi
    else
        echo "  [DEBUG] dmidecode NON trouvé (command -v failed)"
        log_warn "dmidecode non disponible - infos RAM limitées"
    fi
    echo "  [DEBUG] Fin collect_ram_info"

    RAM_INFO=$(jq -n \
        --argjson total "$total_mb" \
        --argjson used "$used_mb" \
        --argjson free "$free_mb" \
        --argjson shared "$shared_mb" \
        --argjson slots_total "${slots_total:-null}" \
        --argjson slots_used "${slots_used:-null}" \
        --argjson ecc "${ecc:-null}" \
        --argjson layout "$layout" \
        '{
            total_mb: $total,
            used_mb: $used,
            free_mb: $free,
            shared_mb: $shared,
            slots_total: $slots_total,
            slots_used: $slots_used,
            ecc: $ecc,
            layout: $layout
        }')

    log_info "RAM Total: ${total_mb}MB (Utilisée: ${used_mb}MB, Libre: ${free_mb}MB)"
    [[ "$shared_mb" -gt 0 ]] && log_info "RAM Partagée: ${shared_mb}MB (tmpfs/vidéo)"
    [[ "$slots_used" != "null" ]] && log_info "Slots: ${slots_used}/${slots_total}"
}

#
# ÉTAPE 4 : Collecte informations GPU, Motherboard, BIOS
#
collect_hardware_info() {
    log_step "Collecte GPU, Carte mère, BIOS"

    # GPU
    local gpu_vendor="null"
    local gpu_model="null"
    local gpu_vram="null"

    if command -v lspci &> /dev/null; then
        local gpu_info=$(lspci | grep -i 'vga\|3d' | head -1)
        if [[ -n "$gpu_info" ]]; then
            gpu_model=$(echo "$gpu_info" | sed 's/.*: //' | xargs)

            if echo "$gpu_info" | grep -qi 'nvidia'; then
                gpu_vendor="NVIDIA"
                if command -v nvidia-smi &> /dev/null; then
                    gpu_vram=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | head -1)
                fi
            elif echo "$gpu_info" | grep -qi 'intel'; then
                gpu_vendor="Intel"
            elif echo "$gpu_info" | grep -qi 'amd\|radeon'; then
                gpu_vendor="AMD"
            fi

            log_info "GPU: $gpu_model"
        fi
    fi

    GPU_INFO=$(jq -n \
        --arg vendor "${gpu_vendor}" \
        --arg model "${gpu_model}" \
        --argjson vram "${gpu_vram:-null}" \
        '{vendor: $vendor, model: $model, vram_mb: $vram}')

    # Motherboard & BIOS
    local mb_manufacturer="null"
    local mb_model="null"
    local bios_vendor="null"
    local bios_version="null"
    local bios_date="null"

    if command -v dmidecode &> /dev/null; then
        mb_manufacturer=$(sudo dmidecode -t 2 | grep 'Manufacturer:' | sed 's/.*: *//' | xargs)
        mb_model=$(sudo dmidecode -t 2 | grep 'Product Name:' | sed 's/.*: *//' | xargs)
        [[ -z "$mb_model" || "$mb_model" == "To be filled by O.E.M." ]] && mb_model="Unknown"

        bios_vendor=$(sudo dmidecode -t 0 | grep 'Vendor:' | sed 's/.*: *//' | xargs)
        bios_version=$(sudo dmidecode -t 0 | grep 'Version:' | sed 's/.*: *//' | xargs)
        bios_date=$(sudo dmidecode -t 0 | grep 'Release Date:' | sed 's/.*: *//' | xargs)

        log_info "Motherboard: $mb_manufacturer $mb_model"
        log_info "BIOS: $bios_version ($bios_date)"
    fi

    MOTHERBOARD_INFO=$(jq -n \
        --arg manu "${mb_manufacturer}" \
        --arg model "${mb_model}" \
        --arg bios_vendor "${bios_vendor}" \
        --arg bios_ver "${bios_version}" \
        --arg bios_date "${bios_date}" \
        '{
            manufacturer: $manu,
            model: $model,
            bios_vendor: $bios_vendor,
            bios_version: $bios_ver,
            bios_date: $bios_date
        }')
}

#
# ÉTAPE 5 : Collecte informations Storage
#
collect_storage_info() {
    log_step "Collecte des informations de stockage"

    local storage_array="[]"

    # Lister uniquement les disques physiques (pas loop, pas ram)
    local physical_disks=$(lsblk -d -n -o NAME,TYPE | grep 'disk' | awk '{print $1}')

    for disk in $physical_disks; do
        # Ignorer les disques de taille 0 (lecteurs vides)
        local size_bytes=$(lsblk -d -n -b -o SIZE /dev/$disk)
        [[ "$size_bytes" -eq 0 ]] && continue

        local size=$(lsblk -d -n -o SIZE /dev/$disk | sed 's/,/./')
        local rota=$(lsblk -d -n -o ROTA /dev/$disk)
        local tran=$(lsblk -d -n -o TRAN /dev/$disk)

        # Type : SSD ou HDD
        local disk_type="unknown"
        [[ "$rota" == "0" ]] && disk_type="ssd" || disk_type="hdd"

        # Interface
        local interface="unknown"
        [[ -n "$tran" ]] && interface="$tran"

        # Modèle et données SMART via smartctl
        local model="Unknown"
        local serial="Unknown"
        local smart_health="null"
        local power_on_hours="null"
        local power_cycle_count="null"
        local temperature="null"
        local reallocated_sectors="null"
        local pending_sectors="null"
        local udma_crc_errors="null"
        local wear_leveling="null"
        local total_lbas_written="null"

        if command -v smartctl &> /dev/null; then
            # Informations de base
            local smart_info=$(sudo smartctl -i /dev/$disk 2>/dev/null || true)
            if [[ -n "$smart_info" ]]; then
                model=$(echo "$smart_info" | grep 'Device Model:' | sed 's/.*: *//' | xargs)
                [[ -z "$model" ]] && model=$(echo "$smart_info" | grep 'Model Number:' | sed 's/.*: *//' | xargs)
                serial=$(echo "$smart_info" | grep 'Serial Number:' | sed 's/.*: *//' | xargs)
            fi

            # Données SMART (santé et vieillissement)
            local smart_all=$(sudo smartctl -A -H /dev/$disk 2>/dev/null || true)
            if [[ -n "$smart_all" ]]; then
                # État de santé global
                if echo "$smart_all" | grep -q 'SMART overall-health self-assessment test result: PASSED'; then
                    smart_health="PASSED"
                elif echo "$smart_all" | grep -q 'SMART overall-health self-assessment test result: FAILED'; then
                    smart_health="FAILED"
                fi

                # Heures de fonctionnement (ID 9)
                power_on_hours=$(echo "$smart_all" | awk '/Power_On_Hours|Power On Hours/ {print $10}' | head -1)
                [[ -z "$power_on_hours" ]] && power_on_hours="null"

                # Nombre de cycles d'alimentation (ID 12)
                power_cycle_count=$(echo "$smart_all" | awk '/Power_Cycle_Count|Start_Stop_Count/ {print $10}' | head -1)
                [[ -z "$power_cycle_count" ]] && power_cycle_count="null"

                # Température (ID 194)
                temperature=$(echo "$smart_all" | awk '/Temperature_Celsius|Airflow_Temperature/ {print $10}' | head -1)
                [[ -z "$temperature" ]] && temperature="null"

                # Secteurs réalloués (ID 5) - Important pour la santé
                reallocated_sectors=$(echo "$smart_all" | awk '/Reallocated_Sector_Ct/ {print $10}' | head -1)
                [[ -z "$reallocated_sectors" ]] && reallocated_sectors="null"

                # Secteurs en attente de réallocation (ID 197)
                pending_sectors=$(echo "$smart_all" | awk '/Current_Pending_Sector/ {print $10}' | head -1)
                [[ -z "$pending_sectors" ]] && pending_sectors="null"

                # Erreurs CRC UDMA (ID 199) - Problèmes de câble/interface
                udma_crc_errors=$(echo "$smart_all" | awk '/UDMA_CRC_Error_Count/ {print $10}' | head -1)
                [[ -z "$udma_crc_errors" ]] && udma_crc_errors="null"

                # Pour SSD: Wear Leveling Count (ID 177)
                if [[ "$disk_type" == "ssd" ]]; then
                    wear_leveling=$(echo "$smart_all" | awk '/Wear_Leveling_Count/ {print $4}' | head -1)
                    [[ -z "$wear_leveling" ]] && wear_leveling="null"

                    # Total LBAs Written (indicateur d'usure SSD, ID 241)
                    total_lbas_written=$(echo "$smart_all" | awk '/Total_LBAs_Written/ {print $10}' | head -1)
                    [[ -z "$total_lbas_written" ]] && total_lbas_written="null"
                fi
            fi
        fi

        # Convertir size en GB
        local size_gb=$(echo "$size" | sed 's/[^0-9.]//g')

        # Créer l'objet SMART
        local smart_json=$(jq -n \
            --arg health "${smart_health}" \
            --argjson power_hours "${power_on_hours:-null}" \
            --argjson power_cycles "${power_cycle_count:-null}" \
            --argjson temp "${temperature:-null}" \
            --argjson realloc "${reallocated_sectors:-null}" \
            --argjson pending "${pending_sectors:-null}" \
            --argjson crc_errors "${udma_crc_errors:-null}" \
            --argjson wear "${wear_leveling:-null}" \
            --argjson lbas_written "${total_lbas_written:-null}" \
            '{
                health_status: $health,
                power_on_hours: $power_hours,
                power_cycle_count: $power_cycles,
                temperature_celsius: $temp,
                reallocated_sectors: $realloc,
                pending_sectors: $pending,
                udma_crc_errors: $crc_errors,
                wear_leveling_count: $wear,
                total_lbas_written: $lbas_written
            }')

        local disk_json=$(jq -n \
            --arg device "$disk" \
            --arg model "$model" \
            --arg size "$size_gb" \
            --arg type "$disk_type" \
            --arg interface "$interface" \
            --arg serial "$serial" \
            --argjson smart "$smart_json" \
            '{device: $device, model: $model, size_gb: $size, type: $type, interface: $interface, serial: $serial, smart: $smart}')

        storage_array=$(echo "$storage_array" | jq --argjson disk "$disk_json" '. + [$disk]')

        # Log avec infos de santé
        local health_info=""
        [[ "$smart_health" != "null" ]] && health_info=" - Santé: $smart_health"
        [[ "$power_on_hours" != "null" ]] && health_info="$health_info, ${power_on_hours}h"
        log_info "Disque: /dev/$disk - $model ($size, $disk_type)$health_info"
    done

    STORAGE_INFO="$storage_array"
}

#
# ÉTAPE 6 : Collecte informations réseau
#
collect_network_info() {
    log_step "Collecte des informations réseau"

    local network_array="[]"

    # Interfaces actives (ignore loopback, docker, bridges)
    for iface in $(ip -br link show | grep -E 'UP|UNKNOWN' | awk '{print $1}'); do
        [[ "$iface" =~ ^(lo|docker|br-|veth) ]] && continue

        # MAC
        local mac=$(ip link show $iface | grep 'link/ether' | awk '{print $2}')
        [[ -z "$mac" ]] && continue

        # Type
        local type="unknown"
        if [[ "$iface" =~ ^(eth|eno|enp) ]]; then
            type="ethernet"
        elif [[ "$iface" =~ ^(wlan|wlp) ]]; then
            type="wifi"
        fi

        # IP address
        local ip_addr=$(ip -4 addr show $iface | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)

        # Vitesse et Wake-on-LAN (nécessite ethtool et ethernet)
        local speed="null"
        local wol_supported="null"
        if command -v ethtool &> /dev/null && [[ "$type" == "ethernet" ]]; then
            speed=$(sudo ethtool $iface 2>/dev/null | grep 'Speed:' | awk '{print $2}' | sed 's/Mb\/s//' | sed 's/Unknown!/null/')
            [[ -z "$speed" || "$speed" == "Unknown" ]] && speed="null"

            # Wake-on-LAN support
            local wol_info=$(sudo ethtool $iface 2>/dev/null | grep 'Supports Wake-on:')
            if [[ -n "$wol_info" ]]; then
                # Si le support contient 'g' (magic packet), WoL est supporté
                if echo "$wol_info" | grep -q 'g'; then
                    wol_supported="true"
                else
                    wol_supported="false"
                fi
            fi
        fi

        local net_json=$(jq -n \
            --arg name "$iface" \
            --arg type "$type" \
            --arg mac "$mac" \
            --arg ip "${ip_addr:-null}" \
            --argjson speed "${speed:-null}" \
            --argjson wol "${wol_supported:-null}" \
            '{name: $name, type: $type, mac: $mac, ip_address: $ip, speed_mbps: $speed, wake_on_lan: $wol}')

        network_array=$(echo "$network_array" | jq --argjson net "$net_json" '. + [$net]')

        log_info "Interface: $iface ($type) - IP: ${ip_addr:-N/A}"
    done

    NETWORK_INFO="$network_array"
}

#
# ÉTAPE 7 : Exécution des benchmarks
#
run_benchmarks() {
    log_step "Exécution des benchmarks (peut prendre plusieurs minutes)"

    # CPU Benchmark
    local cpu_bench="null"
    if command -v sysbench &> /dev/null; then
        log_info "Benchmark CPU en cours..."
        local cpu_result=$(sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) run 2>&1)
        local events_per_sec=$(echo "$cpu_result" | grep 'events per second' | awk '{print $4}')
        local total_time=$(echo "$cpu_result" | grep 'total time:' | awk '{print $3}' | sed 's/s//')
        local cpu_score=$(echo "scale=2; $events_per_sec / 100" | bc)

        cpu_bench=$(jq -n \
            --argjson eps "${events_per_sec:-0}" \
            --argjson time "${total_time:-0}" \
            --argjson score "${cpu_score:-0}" \
            '{events_per_sec: $eps, duration_s: $time, score: $score}')

        log_info "CPU: ${events_per_sec} events/sec (score: ${cpu_score})"
    else
        log_warn "sysbench non disponible - CPU bench ignoré"
    fi

    # Memory Benchmark
    local mem_bench="null"
    if command -v sysbench &> /dev/null; then
        log_info "Benchmark Mémoire en cours..."
        local mem_result=$(sysbench memory --memory-block-size=1M --memory-total-size=1G run 2>&1)
        local throughput=$(echo "$mem_result" | grep 'MiB/sec' | grep -oP '\d+\.\d+' | head -1)
        local mem_score=$(echo "scale=2; $throughput / 100" | bc)

        mem_bench=$(jq -n \
            --argjson tp "${throughput:-0}" \
            --argjson score "${mem_score:-0}" \
            '{throughput_mib_s: $tp, score: $score}')

        log_info "Mémoire: ${throughput} MiB/s (score: ${mem_score})"
    fi

    # Disk Benchmark (sur le disque principal uniquement, pas /tmp)
    local disk_bench="null"
    if command -v fio &> /dev/null; then
        log_info "Benchmark Disque en cours (cela peut prendre 2-3 minutes)..."

        # Utiliser le répertoire home pour éviter /tmp (qui peut être tmpfs)
        local test_dir="$HOME/fio-bench-test"
        mkdir -p "$test_dir"

        local fio_result=$(fio --name=bench --ioengine=libaio --rw=randrw --bs=4k \
            --size=500M --numjobs=1 --direct=1 --runtime=30 --time_based \
            --filename="$test_dir/testfile" --output-format=json 2>/dev/null || echo '{}')

        # Nettoyer
        rm -rf "$test_dir"

        if [[ "$fio_result" != "{}" ]]; then
            local read_bw=$(echo "$fio_result" | jq '.jobs[0].read.bw // 0')
            local write_bw=$(echo "$fio_result" | jq '.jobs[0].write.bw // 0')
            local read_iops=$(echo "$fio_result" | jq '.jobs[0].read.iops // 0' | cut -d. -f1)
            local write_iops=$(echo "$fio_result" | jq '.jobs[0].write.iops // 0' | cut -d. -f1)
            local lat_ns=$(echo "$fio_result" | jq '.jobs[0].read.clat_ns.mean // 0')

            # Convertir en MB/s et ms
            local read_mb=$(echo "scale=2; $read_bw / 1024" | bc)
            local write_mb=$(echo "scale=2; $write_bw / 1024" | bc)
            local lat_ms=$(echo "scale=3; $lat_ns / 1000000" | bc)

            # Score : moyenne read/write MB/s
            local disk_score=$(echo "scale=2; ($read_mb + $write_mb) / 2" | bc)

            disk_bench=$(jq -n \
                --argjson read "$read_mb" \
                --argjson write "$write_mb" \
                --argjson riops "$read_iops" \
                --argjson wiops "$write_iops" \
                --argjson lat "$lat_ms" \
                --argjson score "$disk_score" \
                '{read_mb_s: $read, write_mb_s: $write, iops_read: $riops, iops_write: $wiops, latency_ms: $lat, score: $score}')

            log_info "Disque: R=${read_mb}MB/s W=${write_mb}MB/s (score: ${disk_score})"
        fi
    else
        log_warn "fio non disponible - Disk bench ignoré"
    fi

    # Network Benchmark vers le serveur 10.0.0.50
    local net_bench="null"
    if command -v iperf3 &> /dev/null; then
        log_info "Benchmark Réseau en cours (vers 10.0.0.50)..."

        # Test de connectivité d'abord
        if ping -c 1 -W 2 10.0.0.50 &> /dev/null; then
            # Test upload (client → serveur)
            local upload_result=$(iperf3 -c 10.0.0.50 -t 10 -J 2>/dev/null || echo '{}')

            local upload_mbps="0"
            local download_mbps="0"
            local ping_ms="null"

            if [[ "$upload_result" != "{}" ]]; then
                # Extraire le débit d'upload en bits/sec et convertir en Mbps
                local upload_bps=$(echo "$upload_result" | jq '.end.sum_sent.bits_per_second // 0')
                upload_mbps=$(echo "scale=2; $upload_bps / 1000000" | bc)

                # Test download (serveur → client avec -R)
                local download_result=$(iperf3 -c 10.0.0.50 -t 10 -R -J 2>/dev/null || echo '{}')
                if [[ "$download_result" != "{}" ]]; then
                    local download_bps=$(echo "$download_result" | jq '.end.sum_received.bits_per_second // 0')
                    download_mbps=$(echo "scale=2; $download_bps / 1000000" | bc)
                fi

                # Mesurer le ping
                local ping_output=$(ping -c 5 10.0.0.50 2>/dev/null | grep 'avg' || echo "")
                if [[ -n "$ping_output" ]]; then
                    ping_ms=$(echo "$ping_output" | awk -F'/' '{print $5}')
                fi

                # Score réseau : moyenne upload/download divisée par 10 (pour avoir un score sur 100)
                local net_score=$(echo "scale=2; ($upload_mbps + $download_mbps) / 20" | bc)

                net_bench=$(jq -n \
                    --argjson upload "$upload_mbps" \
                    --argjson download "$download_mbps" \
                    --argjson ping "${ping_ms:-null}" \
                    --argjson score "$net_score" \
                    '{upload_mbps: $upload, download_mbps: $download, ping_ms: $ping, score: $score}')

                log_info "Réseau: ↑${upload_mbps}Mbps ↓${download_mbps}Mbps (ping: ${ping_ms}ms, score: ${net_score})"
            else
                log_warn "Serveur iperf3 sur 10.0.0.50 non accessible (assurez-vous que 'iperf3 -s' tourne)"
            fi
        else
            log_warn "Serveur 10.0.0.50 non joignable - Network bench ignoré"
        fi
    else
        log_warn "iperf3 non disponible - Network bench ignoré"
    fi

    # GPU Benchmark
    local gpu_bench="null"
    log_warn "GPU bench non implémenté - ignoré"

    # Calculer score global (seulement CPU, RAM, Disk)
    # Pondération : CPU=60%, RAM=20%, Disk=20%
    local scores=""
    local total_weight=0

    if [[ "$cpu_bench" != "null" ]]; then
        local cpu_score
        cpu_score=$(echo "$cpu_bench" | jq '.score // 0')
        scores="$scores + $cpu_score * 0.6"
        total_weight=$(safe_bc "$total_weight + 0.6")
    fi

    if [[ "$mem_bench" != "null" ]]; then
        local mem_score
        mem_score=$(echo "$mem_bench" | jq '.score // 0')
        scores="$scores + $mem_score * 0.2"
        total_weight=$(safe_bc "$total_weight + 0.2")
    fi

    if [[ "$disk_bench" != "null" ]]; then
        local disk_score
        disk_score=$(echo "$disk_bench" | jq '.score // 0')
        scores="$scores + $disk_score * 0.2"
        total_weight=$(safe_bc "$total_weight + 0.2")
    fi

    # Nettoyer le préfixe " + " éventuellement
    scores=$(echo "$scores" | sed -E 's/^[[:space:]]*\+ //')

    local global_score=0
    if [[ -n "$scores" && "$total_weight" != "0" ]]; then
        global_score=$(safe_bc "scale=2; ($scores) / $total_weight")
    fi

    # Toujours fournir un JSON valide à jq
    if [[ -z "$global_score" ]]; then
        global_score=0
    fi

    BENCHMARK_RESULTS=$(jq -n \
        --argjson cpu "$cpu_bench" \
        --argjson mem "$mem_bench" \
        --argjson disk "$disk_bench" \
        --argjson net "$net_bench" \
        --argjson gpu "$gpu_bench" \
        --argjson global "$global_score" \
        '{
            cpu: $cpu,
            memory: $mem,
            disk: $disk,
            network: $net,
            gpu: $gpu,
            global_score: $global
        }')

    log_info "Score global: ${global_score}/100"
}

#
# ÉTAPE 8 : Génération du fichier JSON
#
generate_json() {
    log_step "Génération du fichier result.json"

    local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

    # Assembler le JSON final
    jq -n \
        --arg version "$SCRIPT_VERSION" \
        --arg timestamp "$timestamp" \
        --argjson system "$SYSTEM_INFO" \
        --argjson cpu "$CPU_INFO" \
        --argjson ram "$RAM_INFO" \
        --argjson gpu "$GPU_INFO" \
        --argjson mb "$MOTHERBOARD_INFO" \
        --argjson storage "$STORAGE_INFO" \
        --argjson network "$NETWORK_INFO" \
        --argjson benchmarks "$BENCHMARK_RESULTS" \
        '{
            metadata: {
                script_version: $version,
                timestamp: $timestamp
            },
            system: $system,
            hardware: {
                cpu: $cpu,
                ram: $ram,
                gpu: $gpu,
                motherboard: $mb,
                storage: $storage,
                network: $network
            },
            benchmarks: $benchmarks
        }' > "$OUTPUT_FILE"

    log_info "Fichier généré: $OUTPUT_FILE"

    # Afficher un résumé
    echo ""
    echo -e "${GREEN}════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}  Test terminé avec succès !${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════${NC}"
    echo ""
    echo "Fichier de résultat : $(pwd)/$OUTPUT_FILE"
    echo "Taille du fichier   : $(du -h $OUTPUT_FILE | awk '{print $1}')"
    echo ""
    echo "Aperçu du résultat :"
    echo "-------------------"
    jq '{
        hostname: .system.hostname,
        os: .system.os.name,
        cpu: .hardware.cpu.model,
        ram_mb: .hardware.ram.total_mb,
        storage_count: (.hardware.storage | length),
        network_count: (.hardware.network | length),
        benchmark_score: .benchmarks.global_score
    }' "$OUTPUT_FILE"
    echo ""
}

#
# MAIN
#
main() {
    # Vérifications préliminaires
    check_sudo
    check_dependencies

    echo ""
    echo -e "${BLUE}Début de la collecte et des benchmarks...${NC}"
    echo ""

    # Exécuter toutes les étapes
    collect_system_info
    collect_cpu_info
    collect_ram_info
    collect_hardware_info
    collect_storage_info
    collect_network_info
    run_benchmarks
    generate_json

    echo -e "${GREEN}✓ Terminé !${NC}"
}

# Lancer le script
main "$@"
