#!/usr/bin/bash
set -Eeuo pipefail

exec 9>/run/nabu-kernel-update.lock
flock -n 9 || exit 0

if [[ -r /sys/firmware/devicetree/base/compatible ]] &&
   ! grep -aq 'xiaomi,nabu' /sys/firmware/devicetree/base/compatible; then
    printf 'This is not a Xiaomi Pad 5 (nabu); skipping the device kernel update.\n'
    exit 0
fi

selector_package=senemos-nabu-kernel-mainline-alpha
core_package=senemos-nabu-kernel-mainline-alpha-core

dnf5 --assumeyes --refresh upgrade "$selector_package"

latest_core_nevra="$(
    rpm -q --last "$core_package" |
        sed -n '1s/[[:space:]].*//p'
)"
[[ -n "$latest_core_nevra" ]] || {
    printf 'No installed %s package was found.\n' "$core_package" >&2
    exit 1
}

mapfile -t packaged_kernels < <(
    rpm -ql "$latest_core_nevra" | sed -n 's@^/boot/vmlinuz-@@p'
)
[[ "${#packaged_kernels[@]}" -eq 1 ]] || {
    printf 'Expected exactly one kernel in %s; found %s.\n' \
        "$latest_core_nevra" "${#packaged_kernels[@]}" >&2
    exit 1
}
latest_kernel="${packaged_kernels[0]}"
[[ -d "/usr/lib/modules/$latest_kernel" ]] || {
    printf 'The packaged Nabu module tree is missing: %s\n' "$latest_kernel" >&2
    exit 1
}

build_version="$(sed -nE 's/.*-(v[0-9]+([.][0-9]+)+)(-|$).*/\1/p' <<<"$latest_kernel" | head -n1)"
[[ -n "$build_version" ]] || build_version="$latest_kernel"
expected_efi_path="/EFI/SENEMOS/SENEMOS-Nabu-Kernel-${build_version}.efi"

marker=/var/lib/nabu-kernel-update/installed-kernel
entry=/boot/efi/loader/entries/senemos.conf
needs_regeneration=1
if [[ -r "$marker" && "$(<"$marker")" == "$latest_kernel" && -r "$entry" ]]; then
    efi_path="$(sed -nE 's@^efi[[:space:]]+(/.*)@\1@p' "$entry" | head -n1)"
    if [[ "$efi_path" == "$expected_efi_path" && -s "/boot/efi${efi_path}" ]]; then
        needs_regeneration=0
    fi
fi

if (( needs_regeneration )); then
    /usr/bin/nabu-regenerate-uki "$latest_kernel"
fi

efi_path="$(sed -nE 's@^efi[[:space:]]+(/.*)@\1@p' "$entry" | head -n1)"
[[ "$efi_path" == "$expected_efi_path" && -s "/boot/efi${efi_path}" ]] || {
    printf 'The canonical Nabu boot entry does not point to the packaged UKI: %s\n' \
        "$expected_efi_path" >&2
    exit 1
}

# The old stable package may leave depmod-generated files behind. Keep the
# running kernel and every complete fallback tree; an installed module package
# always retains its kernel/ directory even when the top-level directory itself
# is not explicitly owned by RPM.
running_kernel="$(uname -r)"
for module_dir in /usr/lib/modules/*-nabu-senemos-v*; do
    [[ -d "$module_dir" ]] || continue
    module_kernel="${module_dir##*/}"
    [[ "$module_kernel" == "$latest_kernel" || "$module_kernel" == "$running_kernel" ]] && continue
    if [[ ! -d "$module_dir/kernel" ]]; then
        rm -rf --one-file-system -- "$module_dir"
        printf 'Removed orphaned Nabu module tree: %s\n' "$module_kernel"
    fi
done

for protected_entry in android.conf gnome.conf; do
    protected_entry_path="/boot/efi/loader/entries/$protected_entry"
    [[ -r "$protected_entry_path" ]] || continue
    protected_efi="$(sed -nE 's@^efi[[:space:]]+(/.*)@\1@p' "$protected_entry_path" | head -n1)"
    [[ -n "$protected_efi" && -s "/boot/efi${protected_efi}" ]] || {
        printf 'Protected boot entry is missing its EFI payload: %s\n' "$protected_entry" >&2
        exit 1
    }
done

install -d -m0755 /var/lib/nabu-kernel-update
printf '%s\n' "$latest_kernel" > "$marker"
printf 'Nabu kernel and UKI are current: %s (%s)\n' "$latest_kernel" "$efi_path"
