#!/usr/bin/env bash

# Copyright 2023-2024 Gentoo Authors
# This script is installed by sys-kernel/installkernel, it is executed by the
# traditional installkernel, NOT by systemd's kernel-install. I.e. this plugin
# is run when the systemd USE flag is disabled or SYSTEMD_KERNEL_INSTALL=0 is
# set in the environment.

ver=${1}
img=${2}

# familiar helpers, we intentionally don't use Gentoo functions.sh
die() {
	echo -e " ${NOCOLOR-\e[1;31m*\e[0m }${*}" >&2
	exit 1
}

einfo() {
	[[ ${INSTALLKERNEL_VERBOSE} == 1 ]] || return 0
	echo -e " ${NOCOLOR-\e[1;32m*\e[0m }${*}"
}

ewarn() {
	echo -e " ${NOCOLOR-\e[1;33m*\e[0m }${*}"
}

find_config_file() {
	file=${1}
	if [[ -f "/etc/kernel/${file}" ]]; then
		echo "/etc/kernel/${file}"
	elif [[ -f "/usr/lib/kernel/${file}" ]]; then
		echo "/usr/lib/kernel/${file}"
	fi
}

main() {
	# re-define for subst to work
	[[ -n ${NOCOLOR+yes} ]] && NOCOLOR=

	if [[ -n "${INSTALLKERNEL_UKI_GENERATOR}" &&
		${INSTALLKERNEL_UKI_GENERATOR} != ukify ]]; then
			# We are not selected as the uki generator
			einfo "uki_generator=${INSTALLKERNEL_UKI_GENERATOR}, skipping ukify"
			exit 0
	fi

	if [[ -n "${INSTALLKERNEL_LAYOUT}" && ${INSTALLKERNEL_LAYOUT} != uki ]]; then
		einfo "layout=${INSTALLKERNEL_LAYOUT}, skipping ukify"
		exit 0
	fi

	# do nothing if somehow ukify is not installed
	if [[ -x /usr/lib/systemd/ukify ]]; then
		ukify=/usr/lib/systemd/ukify
	elif [[ -x /lib/systemd/ukify ]]; then
		ukify=/lib/systemd/ukify
	else
		ewarn "ukify is not installed, not generating an UKI" && exit 0
	fi

	ukify_gen_args=(
		build
		--linux="${img}"
		--uname="${ver}"
		--output="${INSTALLKERNEL_STAGING_AREA}/uki.efi"
	)

	for cpu in intel amd; do
		[[ -f "/boot/${cpu}-uc.img" ]] && ukify_gen_args+=(--microcode="/boot/${cpu}-uc.img")
	done

	initrd="${INSTALLKERNEL_STAGING_AREA}/initrd"
	[[ -f ${initrd} ]] && ukify_gen_args+=(--initrd="${initrd}")

	# Use the same files as systemd's 60-ukify.install
	cmdline=$(find_config_file cmdline)
	[[ "${cmdline}" ]] && ukify_gen_args+=(--cmdline=@"${cmdline}")

	ukiconf=$(find_config_file uki.conf)
	[[ "${ukiconf}" ]] && ukify_gen_args+=(--config="${ukiconf}")

	devicetree_config=$(find_config_file devicetree)
	if [[ "${devicetree_config}" ]]; then
		devicetree_path=$(cat "${devicetree_config}")
		if [[ -f "/usr/lib/firmware/${ver}/device-tree/${devicetree_path}" ]]; then
			ukify_gen_args+=(--devicetree="/usr/lib/firmware/${ver}/device-tree/${devicetree_path}")
		elif [[ -f "/usr/lib/linux-image-${ver}/${devicetree_path}" ]]; then
			ukify_gen_args+=(--devicetree="/usr/lib/linux-image-${ver}/${devicetree_path}")
		elif [[ -f "/usr/lib/modules/${ver}/dtb/${devicetree_path}" ]]; then
			ukify_gen_args+=(--devicetree="/usr/lib/modules/${ver}/dtb/${devicetree_path}")
		fi
	fi

	einfo "Calling ukify with arguments: ${ukify_gen_args[*]}"
	${ukify} "${ukify_gen_args[@]}" || die "Failed to generate UKI"
}

main
