#!/bin/bash
# openSUSE Furcifer GPU Hardware Detection
# Detects GPU vendor and generation, installs appropriate drivers

set -euo pipefail

log() {
    echo "[furcifer-gpu-detect] $*"
}

GPU_VENDOR=""
GPU_MODEL=""
NVIDIA_GEN=""

detect_gpu() {
    local pci_info
    pci_info=$(lspci -nn | grep -E "VGA compatible|3D controller|Display controller" | head -1)

    if [ -z "$pci_info" ]; then
        log "No GPU detected"
        return
    fi

    GPU_MODEL=$(echo "$pci_info" | sed 's/.*: //' | sed 's/ \[.*//')

    if echo "$pci_info" | grep -qi "nvidia"; then
        GPU_VENDOR="nvidia"
        local device_id
        device_id=$(echo "$pci_info" | grep -oP '\[10de:\K[0-9a-f]+')
        # Determine NVIDIA generation based on device ID
        # G04: Fermi (GF1xx) - 400/500 series
        # G05: Kepler/Maxwell (GKxxx/GMxxx) - 600/700/900 series
        # G06: Pascal/Turing/Ampere (GPxxx/TUxxx/GAxxx) - 1000/2000/3000/4000 series (proprietary kmp)
        # G07: Ada Lovelace+ (ADxxx+) - RTX 4000+ series (open kernel module)
        local device_dec=$((16#${device_id:-0}))
        if [ "$device_dec" -lt $((16#1180)) ]; then
            NVIDIA_GEN="G04"
        elif [ "$device_dec" -lt $((16#1b00)) ]; then
            NVIDIA_GEN="G05"
        elif [ "$device_dec" -lt $((16#2680)) ]; then
            NVIDIA_GEN="G06"
        else
            NVIDIA_GEN="G07"
        fi
    elif echo "$pci_info" | grep -qi "amd\|advanced micro devices"; then
        GPU_VENDOR="amd"
    elif echo "$pci_info" | grep -qi "intel"; then
        GPU_VENDOR="intel"
    fi
}

install_nvidia_drivers() {
    log "NVIDIA GPU detected: $GPU_MODEL"

    # Add NVIDIA repository if not present
    if ! zypper lr --uri 2>/dev/null | grep -q "download.nvidia.com"; then
        log "Adding NVIDIA repository..."
        zypper --non-interactive addrepo --refresh https://download.nvidia.com/opensuse/tumbleweed NVIDIA
    fi

    log "Installing NVIDIA drivers..."

    case "${NVIDIA_GEN}" in
        G07)
            # Ada Lovelace+ uses the open kernel module
            zypper --non-interactive install --no-recommends \
                nvidia-open-driver-G07-signed-kmp-meta \
                nvidia-video-G07 nvidia-video-G07-32bit \
                nvidia-gl-G07 nvidia-gl-G07-32bit \
                nvidia-common-G07 \
                nvidia-settings \
                nvidia-modprobe nvidia-persistenced \
                nvidia-userspace-meta-G07 \
                libnvidia-egl-wayland1 libnvidia-egl-wayland1-32bit
            ;;
        G06)
            # Pascal/Ampere uses proprietary kernel module
            zypper --non-interactive install --no-recommends \
                nvidia-driver-G06-kmp-default \
                nvidia-video-G06 nvidia-video-G06-32bit \
                nvidia-gl-G06 nvidia-gl-G06-32bit \
                nvidia-utils-G06 nvidia-settings \
                nvidia-modprobe nvidia-persistenced \
                nvidia-userspace-meta-G06 \
                libnvidia-egl-wayland1 libnvidia-egl-wayland1-32bit
            ;;
        G05)
            zypper --non-interactive install --no-recommends \
                nvidia-gfxG05-kmp-default \
                x11-video-nvidiaG05 x11-video-nvidiaG05-32bit \
                nvidia-glG05 nvidia-glG05-32bit
            ;;
        G04)
            zypper --non-interactive install --no-recommends \
                nvidia-gfxG04-kmp-default \
                x11-video-nvidiaG04 x11-video-nvidiaG04-32bit \
                nvidia-glG04 nvidia-glG04-32bit
            ;;
        *)
            log "Unknown NVIDIA generation, installing G06 as default..."
            zypper --non-interactive install --no-recommends \
                nvidia-driver-G06-kmp-default \
                nvidia-video-G06 nvidia-video-G06-32bit \
                nvidia-gl-G06 nvidia-gl-G06-32bit
            ;;
    esac

    log "NVIDIA drivers installed successfully"
}

install_amd_drivers() {
    log "AMD GPU detected: $GPU_MODEL"
    log "AMD open-source drivers are already in-kernel (amdgpu)"
    log "Installing AMD Vulkan driver..."
    zypper --non-interactive install --no-recommends \
        libvulkan_radeon libvulkan_radeon-32bit \
        mesa-vulkan-radeon mesa-vulkan-radeon-32bit || true
}

install_intel_drivers() {
    log "Intel GPU detected: $GPU_MODEL"
    log "Intel open-source drivers are already in-kernel"
    log "Installing Intel Vulkan driver..."
    zypper --non-interactive install --no-recommends \
        libvulkan_intel libvulkan_intel-32bit \
        intel-media-driver || true
}

# Main
detect_gpu

case "$GPU_VENDOR" in
    nvidia)
        install_nvidia_drivers
        ;;
    amd)
        install_amd_drivers
        ;;
    intel)
        install_intel_drivers
        ;;
    *)
        log "No supported GPU detected or unknown vendor"
        ;;
esac

log "GPU detection and driver installation complete"
exit 0
