#!/bin/sh
set -e

module=nano-xilinx-drv/rhel-1.1.1
kver=$(uname -r)
kernel=""
src="/usr/src/nano-xilinx-drv-rhel-1.1.1"

while getopts 'hk:' opt; do
    case "$opt" in
        h)
            printf "%s: [-hk]\n" "$0"
            printf "See man page\n"
            exit 0
            ;;
        k)
            kernel="-k $OPTARG"
            kver="$OPTARG"
            ;;
    esac
done

sync_kbuild=/usr/bin/enyx-hfp-sync-kbuild
# When run from the unpacked package before usr is fully installed.
selfdir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
if [ -x "$selfdir/enyx-hfp-sync-kbuild" ]; then
    sync_kbuild="$selfdir/enyx-hfp-sync-kbuild"
fi
if [ -x "$sync_kbuild" ]; then
    "$sync_kbuild"
fi

# Drop stale objects shipped from another kernel (causes Exec format error).
if [ -d "$src" ]; then
    echo "Cleaning stale objects in $src"
    find "$src" -maxdepth 1 \( \
        -name '*.o' -o -name '*.ko' -o -name '*.mod' -o -name '*.mod.c' \
        -o -name '*.mod.o' -o -name '.*.cmd' -o -name 'modules.order' \
        -o -name 'Module.symvers' \
    \) -exec rm -f {} +
    kbuild=$(readlink -f "/lib/modules/${kver}/build" 2>/dev/null || true)
    if [ -n "$kbuild" ] && [ -d "$kbuild" ]; then
        make -C "$kbuild" M="$src" clean >/dev/null 2>&1 || :
    fi
fi

# Clean any previously installed version.
version_re='s!nano-xilinx-drv(, |/)([^,]+),.+$!\2!p'
all_versions=$(dkms status nano-xilinx-drv 2>/dev/null | sed -nr "$version_re" | uniq)
echo "DEBUG: Found versions: '$all_versions'"
for current_version in $all_versions; do
    dkms remove "nano-xilinx-drv/$current_version" --all || :
done

if [ -z "$kernel" ]; then
    kernel="-k $kver"
fi

dkms add $module || :
if ! dkms install --force $module $kernel; then
    echo "WARN: dkms install failed"
fi

install_prebuilt() {
    pre="$src/prebuilt/$kver"
    dest="/lib/modules/${kver}/extra"
    if [ ! -d "$pre" ]; then
        return 1
    fi
    for ko in "$pre"/enyx_hfp*.ko.xz; do
        [ -e "$ko" ] || return 1
        built_version=$(modinfo -F version "$ko" 2>/dev/null || true)
        if [ "$built_version" != "rhel-1.1.1" ]; then
            echo "Refusing stale prebuilt module $ko (version=$built_version)" >&2
            return 1
        fi
    done
    echo "Installing prebuilt modules from $pre"
    mkdir -p "$dest"
    cp -a "$pre"/enyx_hfp*.ko.xz "$dest/"
    depmod -a "$kver"
    return 0
}

load_mods() {
    depmod -a "$kver"
    modprobe -r enyx_hfp_net 2>/dev/null || :
    modprobe -r enyx_hfp_tx 2>/dev/null || :
    modprobe -r enyx_hfp_rx 2>/dev/null || :
    modprobe -r enyx_hfp_mm 2>/dev/null || :
    modprobe -r enyx_hfp_id 2>/dev/null || :
    modprobe -r enyx_hfp_pci 2>/dev/null || :
    modprobe -r enyx_hfp 2>/dev/null || :
    modprobe enyx_hfp
    modprobe enyx_hfp_pci
    modprobe enyx_hfp_mm || :
    modprobe enyx_hfp_id || :
    modprobe enyx_hfp_rx || :
    modprobe enyx_hfp_tx || :
    modprobe enyx_hfp_net || :
}

if ! load_mods; then
    echo "DKMS modules failed to load, trying prebuilt modules for $kver"
    dmesg | grep -E 'this_module|enyx_hfp' | tail -5 || true
    if install_prebuilt && load_mods; then
        echo "Prebuilt modules loaded"
    else
        echo "ERROR: could not load enyx_hfp. Typical causes:" >&2
        echo "  - kernel-devel does not match $(uname -r)" >&2
        echo "  - Exec format error / this_module size mismatch (BTF headers)" >&2
        dmesg | tail -15 >&2
        exit 1
    fi
fi


bind="$selfdir/enyx-hfp-bind-devices"
if [ ! -x "$bind" ]; then
    bind=/usr/bin/enyx-hfp-bind-devices
fi
if [ -x "$bind" ]; then
    "$bind" || echo "WARN: bind-devices returned $?"
fi

udevadm trigger >/dev/null 2>&1 || :
udevadm trigger --action=add \
    --subsystem-match=pci \
    --attr-match=vendor=0x1d8f >/dev/null 2>&1 || :
udevadm trigger --action=add \
    --subsystem-match=pci \
    --attr-match=vendor=0x19c1 >/dev/null 2>&1 || :

mkdir -p /etc/modules-load.d
cat > /etc/modules-load.d/enyx_hfp.conf << 'ML'
enyx_hfp
enyx_hfp_pci
enyx_hfp_mm
enyx_hfp_id
enyx_hfp_rx
enyx_hfp_tx
enyx_hfp_net
ML

echo "enyx_hfp loaded on $kver"
lsmod | grep enyx || true
exit 0
