#!/usr/bin/env bash
# =========================================================
# Nom         : check_temp_all.sh
# Objet       : Afficher les températures système en console
#
# Description :
#   - Affiche les températures système détectées via `sensors` (lm-sensors),
#     NVMe et GPU (NVIDIA).
#   - Classe les valeurs par catégorie : CPU, Carte mère, RAM, NVMe, GPU, Autres.
#   - Colore les valeurs selon leur plage :
#         < 30°C  → Bleu
#     30 – 60°C   → Vert
#     60 – 80°C   → Jaune
#       > 80°C    → Rouge
#   - Pour CPU, Carte mère et NVMe, affiche aussi la température "high" (max) en gris.
#   - Option `--raw` : affiche la sortie brute de `sensors`.
#   - Option `--watch` : rafraîchit toutes les 2 secondes (équivalent à `watch -c script.sh`).
#
# Niveaux visuels :
#   🔵 < 30°C   | 🟢 30–60°C | 🟡 60–80°C | 🔴 > 80°C
#
# Utilisation :
#   ./check_temp_all.sh            → Affichage normal
#   ./check_temp_all.sh --raw      → Sortie brute
#   ./check_temp_all.sh --watch    → Rafraîchit toutes les 2s avec couleurs
#
# Prérequis :
#   - Linux (Debian/Ubuntu/Proxmox…)
#   - lm-sensors installé et configuré (`sudo sensors-detect`)
#   - (Optionnel) nvidia-smi pour GPU NVIDIA
# =========================================================

set -euo pipefail
LC_ALL=C

# Couleurs ANSI
BLUE=$'\033[1;34m'
RED=$'\033[1;31m'
GREEN=$'\033[1;32m'
YELLOW=$'\033[1;33m'
CYAN=$'\033[1;36m'
GRAY=$'\033[90m'
RESET=$'\033[0m'
BOLD=$'\033[1m'

show_help() {
    printf "%b\n" "${BOLD}Usage:${RESET} $0 [--raw] [--watch]"
    echo "  --raw     : Affiche la sortie brute de sensors"
    echo "  --watch   : Rafraîchit toutes les 2 secondes (équivalent à: watch -c script.sh)"
    echo "  --help    : Affiche cette aide"
}

print_section() {
    local title="$1"
    printf "\n%b--- %s ---%b\n" "$CYAN" "$title" "$RESET"
}

# Colorise un nombre (°C) selon seuils
colorize_number() {
    local n="$1"
    awk -v n="$n" -v b="$BLUE" -v g="$GREEN" -v y="$YELLOW" -v r="$RED" -v reset="$RESET" 'BEGIN{
        c = (n < 30) ? b : (n < 60) ? g : (n < 80) ? y : r;
        printf "%s%.1f°C%s", c, n, reset;
    }'
}

# Extrait le premier nombre décimal trouvé depuis une chaîne
first_number() {
    grep -Eo '[+-]?[0-9]+(\.[0-9]+)?' | head -n1 | sed -E 's/^\+?//'
}

# Extrait la valeur après "high ="
extract_high() {
    local line="$1"
    local h
    h="$(echo "$line" | grep -Eo 'high[[:space:]]*=[[:space:]]*[+-]?[0-9]+(\.[0-9]+)?' | tail -n1 | awk '{print $NF}' | sed -E 's/^\+?//')"
    echo -n "$h"
}

# Affiche "Nom  temp_coloree  (max: …)"
render_with_high() {
    local name="$1"
    local temp_num="$2"
    local high_num="$3"
    local colored
    colored="$(colorize_number "$temp_num")"
    if [[ -n "${high_num:-}" ]]; then
        printf "%-20s %s  %b(max: %.1f°C)%b\n" "$name" "$colored" "$GRAY" "$high_num" "$RESET"
    else
        printf "%-20s %s\n" "$name" "$colored"
    fi
}

# Options
RAW_MODE=false
WATCH_MODE=false
for arg in "$@"; do
    case "$arg" in
        --raw) RAW_MODE=true ;;
        --watch) WATCH_MODE=true ;;
        --help) show_help; exit 0 ;;
        *) printf "%bOption inconnue:%b %s\n" "$RED" "$RESET" "$arg"; exit 1 ;;
    esac
done

# Mode --raw
if $RAW_MODE; then sensors; exit 0; fi

# Mode --watch : relance le script avec watch -c
if $WATCH_MODE; then
    exec watch -c "$0"
fi

collect_temps() {
    local sensors_out
    sensors_out="$(sensors 2>/dev/null || true)"

    printf "%b\n" "${BOLD}==== TEMPÉRATURES SYSTÈME (auto) ====${RESET}"

    # CPU
    print_section "CPU"
    cpu_lines="$(echo "$sensors_out" | grep -E '^(Package id [0-9]+|Core [0-9]+):' || true)"
    if [[ -n "${cpu_lines:-}" ]]; then
        while IFS= read -r line; do
            name="${line%%:*}"; name="${name%:}"
            after="${line#*:*}"
            temp_num="$(echo "$after" | first_number)"
            high_num="$(extract_high "$line")"
            [[ -n "${temp_num:-}" ]] && render_with_high "$name" "$temp_num" "$high_num"
        done <<< "$cpu_lines"
    else
        echo "(aucune donnée)"
    fi

    # Carte mère
    print_section "Carte mère"
    mb_lines="$(echo "$sensors_out" | grep -E '^(CPUTIN|SYSTIN|PECI Agent 0):' || true)"
    if [[ -n "${mb_lines:-}" ]]; then
        while IFS= read -r line; do
            name="${line%%:*}"
            after="${line#*:*}"
            temp_num="$(echo "$after" | first_number)"
            high_num="$(extract_high "$line")"
            [[ -n "${temp_num:-}" ]] && render_with_high "$name" "$temp_num" "$high_num"
        done <<< "$mb_lines"
    else
        echo "(aucune donnée)"
    fi

    # RAM
    print_section "RAM"
    ram_lines="$(echo "$sensors_out" | grep -Ei 'DIMM' || true)"
    if [[ -n "${ram_lines:-}" ]]; then
        while IFS= read -r line; do
            if grep -q ':' <<< "$line"; then
                name="${line%%:*}"
                after="${line#*:*}"
                temp_num="$(echo "$after" | first_number)"
                [[ -n "${temp_num:-}" ]] && render_with_high "$name" "$temp_num" ""
            fi
        done <<< "$ram_lines"
    else
        echo "(aucune donnée)"
    fi

    # NVMe
    print_section "NVMe"
    nvme_lines="$(echo "$sensors_out" | awk '
        /^nvme-/ {dev=$1; next}
        /Composite:/ && dev!="" {gsub(/^[ \t]+/,"",$0); printf dev": %s\n", $0}
    ' || true)"
    if [[ -n "${nvme_lines:-}" ]]; then
        while IFS= read -r line; do
            name="${line%%:*}"
            after="${line#*:*}"
            temp_num="$(echo "$after" | first_number)"
            high_num="$(extract_high "$line")"
            [[ -n "${temp_num:-}" ]] && render_with_high "$name" "$temp_num" "$high_num"
        done <<< "$nvme_lines"
    else
        echo "(aucune donnée)"
    fi

    # GPU NVIDIA
    print_section "GPU"
    if command -v nvidia-smi &>/dev/null; then
        nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader | while read -r t; do
            printf -v tfmt "%.1f" "$t"
            render_with_high "NVIDIA GPU" "$tfmt" ""
        done
    else
        echo "(aucune donnée)"
    fi

    # Autres
    print_section "Autres"
    other_lines="$(echo "$sensors_out" | grep -i 'temp' | grep -Ev '^(Core|Package id|CPUTIN|SYSTIN|PECI Agent 0|DIMM|nvme-|Adapter:)' || true)"
    if [[ -n "${other_lines:-}" ]]; then
        while IFS= read -r line; do
            if grep -q ':' <<< "$line"; then
                name="${line%%:*}"
                after="${line#*:*}"
                temp_num="$(echo "$after" | first_number)"
                [[ -n "${temp_num:-}" ]] && render_with_high "$name" "$temp_num" ""
            fi
        done <<< "$other_lines"
    else
        echo "(aucune donnée)"
    fi

    printf "%b\n" "${BOLD}=====================================${RESET}"
}

collect_temps
