#!/usr/bin/env bash
# build-kernel.sh — download and build a KASAN Linux bzImage inside the
# Docker repro image. Not run during `docker build`; call from repro.sh or
# manually so the result can be cached under OUTPUT_DIR.
#
# Output: $OUTPUT_DIR/bzImage  (and $OUTPUT_DIR/linux-$KERNEL_VERSION/ tree)
#
# Env:
#   KERNEL_VERSION   default 6.6.144
#   OUTPUT_DIR       default /artifacts
#   KERNEL_JOBS      default $(nproc)
#   FORCE_KERNEL_BUILD=1  rebuild even if bzImage already exists
set -euo pipefail

KERNEL_VERSION="${KERNEL_VERSION:-6.6.144}"
OUTPUT_DIR="${OUTPUT_DIR:-/artifacts}"
KERNEL_JOBS="${KERNEL_JOBS:-$(nproc)}"
SRC_DIR="$OUTPUT_DIR/linux-${KERNEL_VERSION}"
BUILD_DIR="$OUTPUT_DIR/linux-${KERNEL_VERSION}-build"
OUT_BZIMAGE="$OUTPUT_DIR/bzImage"
TARBALL="linux-${KERNEL_VERSION}.tar.xz"
URL="https://cdn.kernel.org/pub/linux/kernel/v${KERNEL_VERSION%%.*}.x/${TARBALL}"

mkdir -p "$OUTPUT_DIR"

if [[ -f "$OUT_BZIMAGE" && "${FORCE_KERNEL_BUILD:-0}" != "1" ]]; then
	echo "[+] Reusing existing kernel: $OUT_BZIMAGE"
	exit 0
fi

if [[ ! -d "$SRC_DIR" ]]; then
	echo "[+] Downloading $URL"
	curl -fL --retry 3 -o "$OUTPUT_DIR/$TARBALL" "$URL"
	echo "[+] Extracting → $SRC_DIR"
	tar -C "$OUTPUT_DIR" -xf "$OUTPUT_DIR/$TARBALL"
fi

echo "[+] Configuring KASAN + device-mapper ($KERNEL_VERSION)"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
make -C "$SRC_DIR" O="$BUILD_DIR" defconfig
"$SRC_DIR/scripts/config" --file "$BUILD_DIR/.config" \
	--enable KASAN --enable KASAN_GENERIC --enable KASAN_INLINE \
	--enable DM --enable BLK_DEV_LOOP \
	--enable DEVTMPFS --enable DEVTMPFS_MOUNT \
	--enable EXT4_FS --enable VIRTIO_NET --enable VIRTIO_PCI \
	--enable SERIAL_8250 --enable SERIAL_8250_CONSOLE \
	--enable CONFIGFS_FS --enable SECURITYFS \
	--set-str SYSTEM_TRUSTED_KEYS "" --set-str SYSTEM_REVOCATION_KEYS ""
make -C "$SRC_DIR" O="$BUILD_DIR" olddefconfig

echo "[+] Building bzImage (-j$KERNEL_JOBS) — this can take a while"
make -C "$SRC_DIR" O="$BUILD_DIR" -j"$KERNEL_JOBS" bzImage

cp -f "$BUILD_DIR/arch/x86/boot/bzImage" "$OUT_BZIMAGE"
echo "[+] Wrote $OUT_BZIMAGE"
strings "$OUT_BZIMAGE" | grep -m1 '^Linux version' || true
