#!/bin/sh

# shellcheck disable=SC1091
. /usr/lib/libalpine.sh

usage() {
	cat <<-__EOF__
$PROGRAM 0.1.26-r0
usage: $PROGRAM <DIR>

Builds a unified EFI kernel image from a kernel and an initrd file.

DIR must contain a mounted boot partition.

Options:
 -h  Show this help.
 -v  Verbose mode. Display whats going on.

__EOF__
	exit 1
}

while getopts "hv" opt; do
	case "$opt" in
	h) usage;;
	v) VERBOSE=1; export VERBOSE;;
	\?) usage;;
	*) usage;;
	esac
done

shift $((OPTIND - 1))

DESTDIR="$1"

[ -z "$DESTDIR" ] || [ ! -f "$DESTDIR/.alpine-release" ] && die "$DESTDIR is not a mounted boot image."
[ ! -d "$DESTDIR/boot" ] && die "$DESTDIR does not have a 'boot' directory."

# shellcheck disable=SC2046
set -- $(ls "$DESTDIR/boot/vmlinuz-"*)
kernel_image="$1"

[ ! -d "$DESTDIR/boot" ] && die "$DESTDIR does not have a 'boot' directory."

kernel_flavor="${kernel_image##*-}"

# efibootguard uses some custom CPU architecture slugs
case "$(uname -m)" in
	x86_64)
		bg_arch="x64"
		;;
	aarch64)
		bg_arch="a64"
		;;
	*)
		die "Unsupported CPU architecture '$(uname -m)'!"
esac

_part="$(findmnt -n -o SOURCE "$DESTDIR")"
_dev="$(readlink -f "/sys/class/block/$_part/..")"
_label="$(findmnt -n -o LABEL "$DESTDIR")"

# build unified initrd if needed
initrd="$DESTDIR/boot/initramfs-$kernel_flavor"
case "$(uname -m)" in
	x86_64)
		cat "$DESTDIR/boot/amd-ucode.img" "$DESTDIR/boot/intel-ucode.img" "$initrd" > "$DESTDIR/uinitrd"
		initrd="$DESTDIR/uinitrd"
		;;
	*)
		;;
esac

# build unified kernel
exec bg_gen_unified_kernel \
	"/usr/lib/efibootguard/kernel-stub$bg_arch.efi" \
	"$DESTDIR/boot/vmlinuz-$kernel_flavor" \
	"$DESTDIR/unified" \
	--cmdline "modules=loop,squashfs,sd-mod,usb-storage quiet console=tty1 console=ttyS0,115200 apkovl=${_dev}5:/rkos-sys-${_label##*-}.apkovl.tar.gz alpine_repo=/media/$_part/apks modloop=LABEL=$_label" \
	--initrd "$initrd"
