#!/bin/bash

# =======================================================================
# Titel       : GuideOS-Trixie-Nvidia.sh Dialog
# Autor Original-Skript: Nightworker
# Datum       : 2026-06-04
# Beschreibung: GUI zur Installation und Deinstallation des NVIDIA-Treibers
# Lizenz      : MIT
# Sprache     : Bash
# =======================================================================

# Theme für dialog festlegen
export DIALOGRC="/usr/share/debian-nvidia-installer/theme.dialogrc"

#=======================================================================================================
#Variablen festlegen
DriverFolder="/usr/local/bin/Nvidia/"
URL="https://de.download.nvidia.com/XFree86/Linux-x86_64/580.159.04/NVIDIA-Linux-x86_64-580.159.04.run"
#URL="https://de.download.nvidia.com/XFree86/Linux-x86_64/595.71.05/NVIDIA-Linux-x86_64-595.71.05.run"
DownloadCommand="wget -P ${DriverFolder} ${URL}"
# Dateinamen aus der URL extrahieren
FileName=$(basename "$URL")
# Verzeichnis + Dateiname zusammensetzen
NvidiaDriver="${DriverFolder}${FileName}"

INSTALL_SKRIPT="/usr/local/bin/nv-inst.sh"
#=======================================================================================================
# Hilfsfunktion für Dialog-Abbrüche (ESC / Cancel)
check_escape() {
    if [ $1 -eq 1 ] || [ $1 -eq 255 ]; then
        clear
        echo "Vorgang abgebrochen."
        exit 1
    fi
}

# Prüfen, ob 'dialog' installiert ist, falls nicht, über CLI nachinstallieren
if ! command -v dialog >/dev/null 2>&1; then
    echo "'dialog' wird installiert..."
    sudo apt update && sudo apt install -y dialog
fi

# Passwort via dialog abfragen
PASSWD=$(dialog --title "Sudo Passwort eingeben" \
                --clear \
                --insecure \
                --passwordbox "\nBitte gib dein Sudo-Passwort ein:" 21 72 \
                3>&1 1>&2 2>&3)
check_escape $?

if [ -z "$PASSWD" ]; then
    dialog --title "Fehler" --msgbox "Kein Passwort eingegeben. Skript wird beendet." 8 50
    clear
    exit 1
fi

# Passwort validieren
echo "$PASSWD" | sudo -S -v 2>/dev/null
if [ $? -ne 0 ]; then
    dialog --title "Fehler" --msgbox "Falsches Passwort. Skript wird beendet." 8 50
    clear
    exit 1
fi

# Keepalive für Sudo im Hintergrund laufen lassen
(
    while true; do
        echo "$PASSWD" | sudo -S -v 2>/dev/null
        sleep 60
    done
) &
SUDO_KEEPALIVE_PID=$!
trap 'kill $SUDO_KEEPALIVE_PID 2>/dev/null; clear' EXIT

# --- NEU: CLI-Flag für die automatisierte Deinstallation von außen ---
if [[ "$1" == "--silent-uninstall" ]]; then
    UNINSTALLER="/usr/bin/nvidia-uninstall"
    PKGS=$(dpkg-query -W -f='${Package}\n' | grep -E '^nvidia-|^libnvidia-|^cuda-' || true)

    # 1. Offizieller NVIDIA-Uninstaller
    if [[ -x "$UNINSTALLER" ]]; then
        echo "$PASSWD" | sudo -S "$UNINSTALLER" --silent || true
    fi

    # 2. Kernel-Module entladen und Pakete entfernen
    if [[ -n "$PKGS" ]]; then
        echo "$PASSWD" | sudo -S modprobe -r nvidia_drm || true
        echo "$PASSWD" | sudo -S modprobe -r nvidia_modeset || true
        echo "$PASSWD" | sudo -S modprobe -r nvidia || true
        echo "$PASSWD" | sudo -S apt-get purge --autoremove -y $PKGS xserver-xorg-video-nvidia
        echo "$PASSWD" | sudo -S apt remove --purge -y '^nvidia-.*'
        echo "$PASSWD" | sudo -S apt autoremove --purge -y
    fi

    # 3. Zusätzliche Komponenten & Dienste aufräumen
    echo "$PASSWD" | sudo -S rm -rf "$DriverFolder"
    echo "$PASSWD" | sudo -S rm -f "$INSTALL_SKRIPT"
    echo "$PASSWD" | sudo -S systemctl disable nv-inst.service
    echo "$PASSWD" | sudo -S rm -f /etc/systemd/system/nv-inst.service

    # 4. Nouveau reaktivieren
    echo "$PASSWD" | sudo -S apt-get install -y xserver-xorg-video-nouveau
    for f in /etc/modprobe.d/*nouveau*.conf; do
        echo "$PASSWD" | sudo -S [[ -f "$f" ]] && rm -f "$f"
    done
    echo "$PASSWD" | sudo -S echo "nouveau" > /etc/modules-load.d/nouveau.conf
    echo "$PASSWD" | sudo -S rm -f /etc/modprobe.d/blacklist-nouveau.conf
    echo "$PASSWD" | sudo -S rm -f /etc/modprobe.d/nvidia-drm.conf

    exit 0
fi
# --- Ende des CLI-Flag Blocks ---


# Main Loop
while true; do
    option=$(dialog --title "Nvidia Treiber Installation" \
                    --clear \
                    --menu "Bitte treffen Sie eine Auswahl (Pfeiltasten = Bewegen, Enter = Bestätigen):" 21 72 4 \
                    "1" "Treiber von Nvidia laden und installieren" \
                    "2" "Nvidia Treiber entfernen" \
                    "3" "Den PC neu starten" \
                    "4" "Das Skript beenden" \
                    3>&1 1>&2 2>&3)

    if [ $? -ne 0 ]; then break; fi

    case $option in
    "1")
        # Versuche zuerst mit nvidia-smi
        GPU_MODEL=$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null)

        # Fallback mit lspci, wenn nvidia-smi nicht verfügbar
        if [ -z "$GPU_MODEL" ]; then
            GPU_MODEL=$(lspci | grep -i nvidia | sed -n 's/.*NVIDIA Corporation \(.*\) (.*/\1/p')
        fi

        # Falls immer noch leer, Abbruch
        if [ -z "$GPU_MODEL" ]; then

            dialog --title "Fehler" --msgbox "Keine NVIDIA-GPU erkannt." 6 40
            exit 1

            ################################################################################
            #zenity --error --title="Fehler" --text="Keine NVIDIA-GPU erkannt." 2>/dev/null#
            #exit 1                                                                        #
            ################################################################################
        fi

        # Info- und Warntext anzeigen
        dialog --title "Nvidia-Treiber Installation" \
               --yes-label "Weiter" \
               --no-label "Abbrechen" \
               --yesno "In diesem PC ist eine $GPU_MODEL verbaut.\n\nDas Installationsskript lädt die Version $FileName direkt von der offiziellen Nvidia-Webseite herunter. Bitte stelle sicher, dass dein PC mit dem Internet verbunden und die Grafikkarte mit dem Treiber kompatibel ist.\n\nAuf älteren Systemen kann die Installation etwas mehr Zeit in Anspruch nehmen.\n\nBitte unterbreche den Vorgang nicht, da dies dazu führen kann, dass der PC anschließend nicht mehr ordnungsgemäß startet." 21 72

        if [ $? -ne 0 ]; then continue; fi

        clear

        # Prüfen auf vorhandene Treiber
        if command -v nvidia-smi >/dev/null && nvidia-smi >/dev/null 2>&1; then
            dialog --title "NVIDIA Treiber gefunden" --msgbox "Es ist bereits ein NVIDIA-Treiber installiert.\n\nBitte deinstalliere diesen zuerst, bevor du fortfährst." 21 72
            continue
        fi

        # Prüfen, ob NVIDIA-Pakete installiert sind
        if dpkg -l | grep -qE "nvidia-driver|nvidia-kernel|nvidia-dkms"; then
            dialog --title "NVIDIA Treiber gefunden" --msgbox "Es sind bereits NVIDIA-Treiberpaket installiert.\n\nBitte deinstalliere diese zuerst, bevor du fortfährst." 21 72
            continue
        fi

        # Falls nichts gefunden: Installation fortsetzen
        echo "Kein NVIDIA-Treiber gefunden. Installation wird fortgesetzt"
        #=============================================================================
        # 32-Bit Architektur aktivieren
        if ! dpkg --print-foreign-architectures | grep -qw i386; then
            echo "🔧 Aktiviere i386-Architektur für 32-Bit-Unterstützung..."
            echo "$PASSWD" | sudo -S dpkg --add-architecture i386
            echo "$PASSWD" | sudo -S apt update
        else
            echo "✔ i386-Unterstützung ist bereits aktiviert."
        fi

        # Notwendige Pakete installieren
        echo "$PASSWD" | sudo -S apt install -y dkms pkg-config libglvnd-dev libgl1-mesa-dev libegl1-mesa-dev

        VERZEICHNIS="/usr/lib32"

        if [ ! -d "$VERZEICHNIS" ]; then
            echo "$PASSWD" | sudo -S mkdir -p "$VERZEICHNIS"
            echo "Verzeichnis wurde erstellt: $VERZEICHNIS"
        else
            echo "Verzeichnis existiert bereits: $VERZEICHNIS"
        fi
        #=============================================================================

        # --- Secure Boot Erkennung ---
        SECUREBOOT="unbekannt"
        if command -v mokutil &>/dev/null; then
            if mokutil --sb-state 2>/dev/null | grep -iq "enabled"; then
                SECUREBOOT="aktiviert"
            else
                SECUREBOOT="deaktiviert"
            fi
        elif [[ -f /sys/firmware/efi/efivars/SecureBoot-* ]]; then
            if hexdump -v -e '/1 "%u"' /sys/firmware/efi/efivars/SecureBoot-* | grep -q 1; then
                SECUREBOOT="aktiviert"
            else
                SECUREBOOT="deaktiviert"
            fi
        fi

        # --- Secure Boot Warnung ---
        if [[ "$SECUREBOOT" == "aktiviert" ]]; then
            dialog --title "Secure Boot aktiv" \
                --msgbox "Secure Boot ist auf diesem System AKTIVIERT.\n\nDer nouveau-Treiber könnte nicht geladen werden, bis Secure Boot deaktiviert oder der Treiber signiert wird." 21 72
        fi
        #=============================================================================

        echo -e "Linux Header werden geladen...\nNouveau wird deaktiviert...\ninitramfs werden aktualisiert..."

        echo "$PASSWD" | sudo -S apt-get install -y wget

        # Linux-Headers werden installiert
        echo "Linux-Headers werden installiert"
        echo "$PASSWD" | sudo -S apt-get install -y linux-headers-$(uname -r)

        # Nouveau deaktivieren
        if ! grep -q "blacklist nouveau" /etc/modprobe.d/*.conf 2>/dev/null; then
            echo "$PASSWD" | sudo -S tee /etc/modprobe.d/blacklist-nouveau.conf > /dev/null <<EOF
blacklist nouveau
options nouveau modeset=0
EOF
            echo "⚠ Nouveau wurde zur Blacklist hinzugefügt"
        else
            echo "✔ Nouveau ist bereits deaktiviert."
        fi

        echo "# Initramfs wird aktualisiert..."
        echo "$PASSWD" | sudo -S update-initramfs -u
        echo "# Fertig."

        # Liste unterstützter Chips für nvidia-open
        SUPPORTED_CHIPS=("RTX 20" "RTX 30" "RTX 40" "A100" "L4" "T4" "A30" "H100")

        # Prüfen, ob Modell in Liste vorkommt
        USE_OPEN="no"
        for chip in "${SUPPORTED_CHIPS[@]}"; do
            if echo "$GPU_MODEL" | grep -qi "$chip"; then
                USE_OPEN="yes"
                break
            fi
        done

        # Entscheidung anzeigen
        if [ "$USE_OPEN" = "yes" ]; then
            dialog --title "Kompatibilität" \
                   --msgbox "✅ Die erkannte GPU \"$GPU_MODEL\" ist mit dem Open-Source-Modul kompatibel.\n\nDu kannst nvidia-open verwenden." 21 72
        else
            dialog --title "Nicht kompatibel" \
                   --msgbox "⚠️ Die erkannte GPU \"$GPU_MODEL\" ist NICHT mit dem Open-Source-Treiber kompatibel.\n\nBitte verwende den proprietären Treiber (closed)." 21 72
        fi

        # Auswahlmenü für kernel-module-type
        KMOD_TYPE=$(dialog --title "Nvidia Treiber-Modul" \
            --radiolist "Wähle den Typ des Kernel-Moduls für die Installation des Nvidia-Treibers:" 21 72 2 \
            "open" "Open-Source-Modul (für neuere GPUs empfohlen)" ON \
            "closed" "Proprietäres Nvidia-Modul verwenden" OFF \
            3>&1 1>&2 2>&3)

        # Prüfen, ob der Benutzer abgebrochen hat
        if [ $? -ne 0 ] || [[ -z "$KMOD_TYPE" ]]; then
            dialog --title "Fehler" \
                   --msgbox "Abbruch durch Benutzer. Keine Auswahl getroffen." 21 72
            clear
            exit 1
        fi

        clear

        # Installationsbefehl vorbereiten
        if [[ "$KMOD_TYPE" == "open" ]]; then
            INSTALL_CMD="sudo bash $NvidiaDriver --install-compat32-libs --compat32-libdir=/usr/lib32 --kernel-module-type=open --install-libglvnd --silent --dkms"
        else
            INSTALL_CMD="sudo bash $NvidiaDriver --install-compat32-libs --compat32-libdir=/usr/lib32 --install-libglvnd --silent --dkms"
        fi

        # Sicherstellen, dass das Verzeichnis existiert
        if [ ! -d "$DriverFolder" ]; then
            echo ""
            echo "---------------------------------------------------"
            echo "Erstelle Verzeichnis: $DriverFolder"
            echo "Bitte warten, bis der Download abgeschlossen ist..."
            echo "---------------------------------------------------"
            echo "$PASSWD" | sudo -S mkdir -p "$DriverFolder"
            echo""
        fi

        # Funktion: Download starten
        if [ ! -f "$NvidiaDriver" ]; then
            echo "$PASSWD" | sudo -S $DownloadCommand
        fi

        # Überprüfen, ob der Download erfolgreich war
        if [ -f "$NvidiaDriver" ]; then
            dialog --title "Erfolg" --msgbox "Download erfolgreich abgeschlossen!\nDer Treiber wude gespeichert unter: $NvidiaDriver" 21 72
        else
            dialog --title "Fehler" --msgbox "Download fehlgeschlagen!" 21 72
            continue
        fi

        clear

        echo "$PASSWD" | sudo -S chmod +x "$NvidiaDriver"

        SERVICEFILE="/etc/systemd/system/nv-inst.service"
        #=============================================================================
 cat << EOI | sudo tee /usr/local/bin/nv-inst.sh > /dev/null
#!/bin/bash
set e
sleep 5

# Theme für dialog festlegen
export DIALOGRC="/usr/share/debian-nvidia-installer/theme.dialogrc"

# Automatisch auf tty3 umschalten
chvt 3
sleep 1   # kurze Pause für sichere Umschaltung

# Alles nach tty3 loggen
exec > /dev/tty3 2>&1

echo ">>> Starte NVIDIA-Treiber Installation auf tty3 ..."
sudo touch /var/log/nvidia-installer.log
LOGFILE="/var/log/nvidia-installer.log"
clear


dialog --title "Installation startet" \
       --colors \
       --timeout 10 \
       --msgbox "Je nach Leistung des PCs kann die Installation\netwas länger dauern.\n\Z1Bitte breche den Vorgang nicht ab.\Zn\n\nDer PC wird im Anschluss automatisch neu gestartet." 10 60
clear

# Installer starten
$INSTALL_CMD

sleep 2

sudo echo "options nvidia-drm modeset=1" | sudo tee /etc/modprobe.d/nvidia-drm.conf > /dev/null

dialog --title "Installation startet" \
       --colors \
       --timeout 5 \
       --msgbox "Nvidia Installation abgeschlossen" 10 60
clear

# Wieder zurück auf tty1 wechseln (für Login/Grafikdisplay)
sleep 1
chvt 1

# Deaktiviere systemd-Dienst
systemctl disable nv-inst.service
#sudo systemctl set-default graphical.target
#sudo reboot
EOI
#=============================================================================
echo "$PASSWD" | sudo -S chmod +x /usr/local/bin/nv-inst.sh
#=============================================================================
cat << EOU | sudo tee /etc/systemd/system/nv-inst.service > /dev/null
[Unit]
Description=Einmalige Nvidia Installation beim Booten ausführen
Before=graphical.target display-manager.service
ConditionPathExists=$NvidiaDriver

[Service]
Type=oneshot
ExecStart=$INSTALL_SKRIPT
StandardOutput=tty
StandardError=tty
TTYPath=/dev/tty1
RemainAfterExit=no

[Install]
WantedBy=graphical.target
EOU
        #=============================================================================
        echo "$PASSWD" | sudo -S systemctl daemon-reexec
        echo "$PASSWD" | sudo -S systemctl daemon-reload
        echo "$PASSWD" | sudo -S systemctl enable nv-inst.service

        dialog --title "Abfrage" --yesno "Der PC wird jetzt neu gestartet und der Treiber installiert." 21 72
        if [ $? -eq 0 ]; then
        clear # Bereinigt den Dialog-Bildschirm vor der Passwort-Eingabe
        echo "$PASSWD" | sudo -S reboot
        fi
        ;;



    "2")
        # --- NVIDIA-Pakete suchen ---
        PKGS=$(dpkg-query -W -f='${Package}\n' | grep -E '^nvidia-|^libnvidia-|^cuda-' || true)
        UNINSTALLER="/usr/bin/nvidia-uninstall"

        if [[ -n "$PKGS" || -x "$UNINSTALLER" ]]; then
            LIST_MSG=""
            [[ -n "$PKGS" ]] && LIST_MSG+="\nGefundene Pakete:\n$PKGS"
            [[ -x "$UNINSTALLER" ]] && LIST_MSG+="\nes ist ein offizieller NVIDIA-Uninstaller vorhanden."

            if ! dialog --title "NVIDIA-Treiber gefunden" \
                        --yesno "\nEs wurde ein installierter NVIDIA-Treiber gefunden und ${LIST_MSG}\n\nMöchten Sie diesen Treiber vollständig entfernen?" 21 72; then

                dialog --title "Abbruch" --msgbox "\nDie Deinstallation wurde abgebrochen." 21 72
                clear
                exit 0
            fi
            clear

            # --- Offizieller NVIDIA-Uninstaller ---
            if [[ -x "$UNINSTALLER" ]]; then
                dialog --title "Entfernung" --msgbox "\nStarte offiziellen NVIDIA-Uninstaller..." 21 72
                sleep 2
                clear
                echo "$PASSWD" | sudo -S "$UNINSTALLER" --silent || true
            fi

            # --- Paket-Deinstallation ---
            if [[ -n "$PKGS" ]]; then
                dialog --title "Entfernung" --infobox "\nEntferne NVIDIA-Pakete..." 21 72
                sleep 2
                clear

                (
                    echo "10"
                    echo "$PASSWD" | sudo -S modprobe -r nvidia_drm || true
                    echo "$PASSWD" | sudo -S modprobe -r nvidia_modeset || true
                    echo "$PASSWD" | sudo -S modprobe -r nvidia || true

                    echo "30"
                    echo "$PASSWD" | sudo -S apt-get purge --autoremove -y $PKGS xserver-xorg-video-nvidia

                    echo "60"
                    echo "$PASSWD" | sudo -S apt remove --purge -y '^nvidia-.*'

                    echo "80"
                    echo "$PASSWD" | sudo -S apt autoremove --purge -y

                    echo "100"
                )

            fi

            # --- Verzeichnisse löschen ---
            echo "$PASSWD" | sudo -S rm -rf "$DriverFolder"
            echo "$PASSWD" | sudo -S rm -f "$INSTALL_SKRIPT"
            echo "$PASSWD" | sudo -S systemctl disable nv-inst.service
            echo "$PASSWD" | sudo -S rm -f /etc/systemd/system/nv-inst.service

            # --- Nouveau installieren ---
            echo "$PASSWD" | sudo -S apt-get install -y xserver-xorg-video-nouveau

            # Blacklist entfernen
            for f in /etc/modprobe.d/*nouveau*.conf; do
                echo "$PASSWD" | sudo -S [[ -f "$f" ]] && rm -f "$f"
            done

            echo "$PASSWD" | sudo -S echo "nouveau" > /etc/modules-load.d/nouveau.conf
            echo "$PASSWD" | sudo -S rm -f /etc/modprobe.d/blacklist-nouveau.conf
            echo "$PASSWD" | sudo -S rm -f /etc/modprobe.d/nvidia-drm.conf

            dialog --title "Fertig" \
                   --msgbox "\nder NVIDIA-Treiber wurde entfernt und der Nouveau-Treiber aktiviert.\n\nBitte starten Sie das System neu." 21 72
            clear
        else
            dialog --title "Keine Treiber" --msgbox "\nEs wurden keine NVIDIA-Treiber gefunden." 21 72
            clear
        fi
        ;;

    "3")
        dialog --title "Neustart" --yesno "🔁 PC wirklich neu starten?" 21 72
        if [ $? -eq 0 ]; then
            clear
            echo "$PASSWD" | sudo -S reboot
        fi
        clear
        ;;

    "4")
        dialog --title "Beenden" --msgbox "👋 Das Skript wird beendet." 21 72
        clear
        exit 0
        ;;
    esac
done
