#!/bin/bash

set -euo pipefail

KVER="${KVER:-5.10.134-19.8.al8.aarch64}"
PACKAGE_DIR="${PACKAGE_DIR:-}"
EVIDENCE_DIR="${EVIDENCE_DIR:-/root/kernel-remediation-$(date +%Y%m%d%H%M%S)}"
CONFIRM="${CONFIRM:-}"

if [ "$(id -u)" -ne 0 ]; then
    echo "ERROR: run as root" >&2
    exit 1
fi

if [ -z "$PACKAGE_DIR" ] || [ ! -d "$PACKAGE_DIR" ]; then
    echo "ERROR: set PACKAGE_DIR to the extracted RPM directory" >&2
    exit 1
fi

mkdir -p "$EVIDENCE_DIR"
exec > >(tee -a "$EVIDENCE_DIR/execution.log") 2>&1

echo "BEGIN=$(date --iso-8601=seconds)"
echo "HOST=$(hostname)"
echo "RUNNING_KERNEL=$(uname -r)"
echo "TARGET_KERNEL=$KVER"

{
    hostname
    ip -4 -o addr show scope global
    date --iso-8601=seconds
    uptime
    uname -r
    df -h / /boot 2>&1 || true
    rpm -qa 'kernel*' | sort
    grubby --default-kernel
    grubby --info=ALL
    systemctl --failed --no-pager
    systemctl list-units --type=service --state=running --no-pager
    ss -lntp
} > "$EVIDENCE_DIR/precheck.txt" 2>&1

if [ -f "$PACKAGE_DIR/SHA256SUMS" ]; then
    (cd "$PACKAGE_DIR" && sha256sum -c SHA256SUMS) \
        > "$EVIDENCE_DIR/package-sha256-check.txt" 2>&1
else
    echo "ERROR: $PACKAGE_DIR/SHA256SUMS is missing" >&2
    exit 1
fi

mapfile -t RPMS < <(
    for name in kernel kernel-core kernel-modules kernel-modules-extra kernel-modules-internal; do
        find "$PACKAGE_DIR" -maxdepth 1 -type f -name "${name}-${KVER}.rpm" -print
    done
)

if [ "${#RPMS[@]}" -ne 5 ]; then
    printf 'ERROR: expected 5 target RPMs, found %s\n' "${#RPMS[@]}" >&2
    printf '%s\n' "${RPMS[@]}" >&2
    exit 1
fi

rpm -K "${RPMS[@]}" > "$EVIDENCE_DIR/rpm-signature-check.txt" 2>&1
if grep -Ev ': digests signatures OK$' "$EVIDENCE_DIR/rpm-signature-check.txt" | grep -q .; then
    echo "ERROR: RPM signature verification failed" >&2
    exit 1
fi

set +e
dnf install --disablerepo='*' --assumeno "${RPMS[@]}" \
    > "$EVIDENCE_DIR/install-preview.txt" 2>&1
PREVIEW_RC=$?
set -e

cat "$EVIDENCE_DIR/install-preview.txt"
echo "PREVIEW_RC=$PREVIEW_RC"
echo "Review the transaction preview before installation."

if [ "$CONFIRM" != "INSTALL-$KVER" ]; then
    echo "STOP: preview only. Re-run with CONFIRM=INSTALL-$KVER after approval."
    exit 2
fi

if grep -Eiq '(^|[[:space:]])(Removing|Downgrading|Erasing|Obsoleting)([[:space:]]|:)' \
    "$EVIDENCE_DIR/install-preview.txt"; then
    echo "ERROR: transaction preview contains removal/downgrade/obsolete action" >&2
    exit 1
fi

dnf install --disablerepo='*' -y "${RPMS[@]}" | tee "$EVIDENCE_DIR/install.log"

rpm -qa 'kernel*' | sort > "$EVIDENCE_DIR/installed-kernel-rpms.txt"
test -f "/boot/vmlinuz-$KVER"
test -f "/boot/initramfs-$KVER.img"
grubby --set-default "/boot/vmlinuz-$KVER"

{
    date --iso-8601=seconds
    rpm -qa 'kernel*' | sort
    df -h /boot
    ls -lh "/boot/vmlinuz-$KVER" "/boot/initramfs-$KVER.img"
    grubby --default-kernel
    grubby --info="/boot/vmlinuz-$KVER"
} > "$EVIDENCE_DIR/post-install-pre-reboot.txt" 2>&1

cat > "$EVIDENCE_DIR/next-step.txt" <<EOF
Installation completed. Reboot is intentionally not automatic.
Confirm the old kernel remains installed and role recovery commands are ready.
In the approved maintenance window run: sync; systemctl reboot
After reconnecting require: uname -r = $KVER
EOF

echo "INSTALL_OK=1"
echo "REBOOT_REQUIRED=1"
echo "EVIDENCE_DIR=$EVIDENCE_DIR"

