# Nomarchy Hardware Database
#
# Flat table mapping detected DMI fields to `nixos-hardware` flake modules.
# Sourced by installer/install.sh at runtime.
#
# Format (pipe-separated):
#   sys_vendor_regex | product_regex | nomarchy_hw_opt | nixos_hardware_module
#
# - Matching is bash `[[ =~ ]]` regex, case-insensitive.
# - Use "_" for `nomarchy_hw_opt` when there's no Nomarchy toggle to set.
# - Multiple modules can be joined with "+" if a device needs >1.
# - First match wins — put more specific entries (e.g. exact model years) above
#   broader fallbacks.
#
# To add a new device: grab the string from `/sys/class/dmi/id/product_name`
# on the target machine and add a line here. See:
#   https://github.com/NixOS/nixos-hardware/tree/master/<vendor>
# for the list of available module attributes.

HARDWARE_DB=(
  # Framework ---------------------------------------------------------------
  "Framework|Laptop 16.*AMD|isFramework=true|framework-16-7040-amd"
  "Framework|Laptop 13.*AMD Ryzen AI 300|isFramework=true|framework-13-amd-ai-300-series"
  "Framework|Laptop 13.*AMD Ryzen 7040|isFramework=true|framework-13-7040-amd"
  "Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13-13th-gen-intel"
  "Framework|Laptop 13.*12th Gen Intel|isFramework=true|framework-13-12th-gen-intel"
  "Framework|Laptop 13.*11th Gen Intel|isFramework=true|framework-13-11th-gen-intel"
  "Framework|Laptop \(13.*|isFramework=true|framework-13-11th-gen-intel"

  # Dell XPS / Precision / Latitude ----------------------------------------
  "Dell|XPS 15 9500|isXPS=true|dell-xps-15-9500"
  "Dell|XPS 15 9510|isXPS=true|dell-xps-15-9510"
  "Dell|XPS 15 9520|isXPS=true|dell-xps-15-9520"
  "Dell|XPS 13 9310|isXPS=true|dell-xps-13-9310"
  "Dell|XPS 13 9370|isXPS=true|dell-xps-13-9370"
  "Dell|XPS 13 9380|isXPS=true|dell-xps-13-9380"
  "Dell|XPS 13 7390|isXPS=true|dell-xps-13-7390"
  "Dell|Precision 5530|_|dell-precision-5530"
  "Dell|Latitude 7480|_|dell-latitude-7480"
  "Dell|Latitude 5400|_|dell-latitude-5400"

  # Lenovo ThinkPad --------------------------------------------------------
  "LENOVO|ThinkPad X1 Carbon Gen 11|_|lenovo-thinkpad-x1-carbon-gen11"
  "LENOVO|ThinkPad X1 Carbon Gen 10|_|lenovo-thinkpad-x1-carbon-gen10"
  "LENOVO|ThinkPad X1 Carbon Gen 9|_|lenovo-thinkpad-x1-carbon-gen9"
  "LENOVO|ThinkPad X1 Extreme|_|lenovo-thinkpad-x1-extreme"
  "LENOVO|ThinkPad T14 Gen 3|_|lenovo-thinkpad-t14-amd-gen3"
  "LENOVO|ThinkPad T14 Gen 2|_|lenovo-thinkpad-t14-amd-gen2"
  "LENOVO|ThinkPad T14 Gen 1|_|lenovo-thinkpad-t14-amd-gen1"
  "LENOVO|ThinkPad T480|_|lenovo-thinkpad-t480"
  "LENOVO|ThinkPad L13|_|lenovo-thinkpad-l13"
  "LENOVO|ThinkPad P14s|_|lenovo-thinkpad-p14s"

  # Microsoft Surface ------------------------------------------------------
  "Microsoft|Surface Pro 9|_|microsoft-surface-pro-9"
  "Microsoft|Surface Pro 8|_|microsoft-surface-pro-8"
  "Microsoft|Surface Pro 7|_|microsoft-surface-pro-7"
  "Microsoft|Surface Pro 6|_|microsoft-surface-pro-6"
  "Microsoft|Surface Laptop 5|_|microsoft-surface-laptop-5"
  "Microsoft|Surface Laptop 4|_|microsoft-surface-laptop-4"
  "Microsoft|Surface Laptop 3|_|microsoft-surface-laptop-3"
  "Microsoft|Surface Go|_|microsoft-surface-go"
  "Microsoft|Surface Book 3|_|microsoft-surface-book-3"
  "Microsoft|Surface Book 2|_|microsoft-surface-book-2"

  # ASUS ROG / Zephyrus ----------------------------------------------------
  "ASUS.*|ROG Zephyrus G14.*2024|_|asus-zephyrus-ga403"
  "ASUS.*|ROG Zephyrus G14.*2023|_|asus-zephyrus-ga402"
  "ASUS.*|ROG Zephyrus G14.*2021|_|asus-zephyrus-ga401"
  "ASUS.*|ROG Zephyrus G15|_|asus-zephyrus-ga503"
  "ASUS.*|ROG Strix G15|_|asus-rog-strix-g513"
  "ASUS.*|Zenbook UX|_|asus-zenbook-ux"

  # Apple (T2 Intel; M-series falls back to asahi elsewhere) ---------------
  "Apple.*|MacBookPro15|isT2Mac=true|apple-t2"
  "Apple.*|MacBookPro16|isT2Mac=true|apple-t2"
  "Apple.*|MacBookAir8|isT2Mac=true|apple-t2"
  "Apple.*|MacBookAir9|isT2Mac=true|apple-t2"
  "Apple.*|iMac19|isT2Mac=true|apple-t2"
  "Apple.*|iMacPro1|isT2Mac=true|apple-t2"

  # System76 ---------------------------------------------------------------
  "System76|Oryx Pro.*|_|system76"
  "System76|Lemur Pro.*|_|system76"
  "System76|Darter Pro.*|_|system76"
  "System76|Galago Pro.*|_|system76"
  "System76|Pangolin.*|_|system76"

  # Raspberry Pi (ARM) — listed for completeness; installer is x86_64 only -
  # "Raspberry Pi|Raspberry Pi 5|_|raspberry-pi-5"
  # "Raspberry Pi|Raspberry Pi 4|_|raspberry-pi-4"
)

# ----------------------------------------------------------------------------
# nomarchy_detect_hw
#
# Inspects DMI + lspci + /sys to figure out which nixos-hardware modules fit
# the running machine. Emits (on stdout) one line per result:
#
#   MODULE  <module-name>
#   OPT     <nomarchy_hw_opt>   # zero or more, one per line
#   DETAIL  <human-readable hit>
#
# Return codes: 0 if at least one module was detected, 1 otherwise.
# ----------------------------------------------------------------------------
nomarchy_detect_hw() {
    local sys_vendor product_name board_name cpu_vendor
    sys_vendor=$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || echo "")
    product_name=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "")
    board_name=$(cat /sys/class/dmi/id/board_name 2>/dev/null || echo "")
    cpu_vendor=$(lscpu 2>/dev/null | awk -F: '/Vendor ID/{gsub(/ /,"",$2); print $2; exit}')

    local detected=0

    # CPU --------------------------------------------------------------------
    case "$cpu_vendor" in
        AuthenticAMD) echo "MODULE common-cpu-amd"; echo "DETAIL cpu: AMD"; detected=1 ;;
        GenuineIntel) echo "MODULE common-cpu-intel"; echo "DETAIL cpu: Intel"; detected=1 ;;
    esac

    # GPU (lspci may list multiple; handle all) -----------------------------
    if command -v lspci >/dev/null 2>&1; then
        local gpu_line nvidia=0 amdgpu=0 intelgpu=0
        while IFS= read -r gpu_line; do
            case "$gpu_line" in
                *"[10de:"*|*"NVIDIA"*) nvidia=1 ;;
                *"[1002:"*|*"AMD/ATI"*|*"Advanced Micro Devices"*) amdgpu=1 ;;
                *"[8086:"*|*"Intel Corporation"*) intelgpu=1 ;;
            esac
        done < <(lspci -nn 2>/dev/null | grep -iE 'vga|3d|display')

        (( nvidia ))   && { echo "MODULE common-gpu-nvidia"; echo "DETAIL gpu: NVIDIA"; detected=1; }
        (( amdgpu ))   && { echo "MODULE common-gpu-amd";    echo "DETAIL gpu: AMD";    detected=1; }
        (( intelgpu )) && { echo "MODULE common-gpu-intel";  echo "DETAIL gpu: Intel";  detected=1; }
    fi

    # Laptop / SSD ----------------------------------------------------------
    if compgen -G "/sys/class/power_supply/BAT*" >/dev/null; then
        echo "MODULE common-pc-laptop"
        echo "DETAIL chassis: laptop (battery present)"
        detected=1
    else
        echo "MODULE common-pc"
        echo "DETAIL chassis: desktop"
        detected=1
    fi

    # Model-specific match from the DB --------------------------------------
    local entry v_re p_re opt mod
    for entry in "${HARDWARE_DB[@]}"; do
        IFS='|' read -r v_re p_re opt mod <<< "$entry"
        shopt -s nocasematch
        if [[ "$sys_vendor" =~ $v_re ]] && [[ "$product_name" =~ $p_re ]]; then
            shopt -u nocasematch
            echo "MODULE $mod"
            [[ "$opt" != "_" ]] && echo "OPT $opt"
            echo "DETAIL model: $sys_vendor $product_name → $mod"
            detected=1
            break
        fi
        shopt -u nocasematch
    done

    return $(( 1 - detected ))
}

# ----------------------------------------------------------------------------
# nomarchy_hw_summary
#
# Pretty-prints the output of `nomarchy_detect_hw` for TUI consumption.
# Reads from stdin.
# ----------------------------------------------------------------------------
nomarchy_hw_summary() {
    local line key val
    while IFS= read -r line; do
        key="${line%% *}"
        val="${line#* }"
        case "$key" in
            DETAIL) echo "  → $val" ;;
        esac
    done
}
