#!/bin/sh

set -e

# Including common functions
( . "${LIVE_BUILD}/scripts/build.sh" > /dev/null 2>&1 || true ) || . /usr/lib/live/build.sh

# Setting static variables
DESCRIPTION="$(Echo 'installs grub2 efi into binary')"
HELP=""
USAGE="${PROGRAM} [--force]"
ARCHITECTURE="$(echo ${LB_ARCHITECTURES} | sed -e 's| |/|g')"
ORIGIN="$(echo $LB_ISO_VOLUME | cut -d '-' -f 1)"

Arguments "${@}"

if [ -f .build/chroot_has_efi ] || [ -f .build/binary_has_efi ];then
  Echo_message "Begin installing grub2 efi..."
else
  Echo_message "Kylin add has .build/no_efi, exit grub2-efi"
  exit 0
fi

# Reading configuration files
Read_conffiles config/all config/common config/bootstrap config/chroot config/binary config/source
Set_defaults

# Requiring stage file
Require_stagefile .build/config .build/bootstrap

# Checking stage file
Check_stagefile .build/binary_grub2_efi

# Checking grub2 templates
Check_templates grub2

# Checking lock file
Check_lockfile .lock

# Creating lock file
Create_lockfile .lock

# Check architecture
Check_architectures amd64 arm64 mips64el loongarch64 sw64
Check_crossarchitectures

# Checking depends
case ${ARCHITECTURE} in
		'amd64'|'arm64'|'mips64el'|'loongarch64'|'sw64')
			Check_package chroot/usr/bin/grub-mkimage grub-efi-${ARCHITECTURE}
			Check_package chroot/sbin/mkfs.fat dosfstools
			Check_package chroot/sbin/MAKEDEV makedev
			;;
        *)
			Echo_message "not amd64 or arm64 or mips64el or loongarch64 or sw64, grub2-efi exit"
			exit 0
			;;
esac

# Restoring cache
Restore_cache cache/packages.binary

# Installing depends
Install_package

case ${LB_BINARY_IMAGES} in
        iso*)
		if [ ! -d chroot/usr/lib/grub/x86_64-efi ] && \
		[ ! -d chroot/usr/lib/grub/arm64-efi ] && \
		[ ! -d chroot/usr/lib/grub/mips64el-efi ] && \
		[ ! -d chroot/usr/lib/grub/sw64-efi ] && \
		[ ! -d chroot/usr/lib/grub/loongarch64-efi ];then
                        exit 0
		fi
                ;;

        *)
                exit 0
                ;;
esac


Echo_message "Begin installing grub2 efi doing..."
# Local functions
Grub_live_entry ()
{
	LABEL="${1}"
	KERNEL="${2}"
	INITRD="${3}"
	APPEND="${4}"
	DEVICETREE="${5}"

	LINUX_LIVE="${LINUX_LIVE}\nmenuentry \"${LABEL}\" {"
	LINUX_LIVE="${LINUX_LIVE}\nlinux\t\t/${KERNEL} ${APPEND}"
	LINUX_LIVE="${LINUX_LIVE}\ninitrd\t\t/${INITRD}"
	if [ -n "$DEVICETREE" ];then
		LINUX_LIVE="${LINUX_LIVE}\ndevicetree\t\t/${DEVICETREE}"
	fi
	LINUX_LIVE="${LINUX_LIVE}\n}"
}

Grub_install_entry ()
{
	LABEL="${1}"
	KERNEL="${2}"
	INITRD="${3}"
	APPEND="${4}"
        DEVICETREE="${5}"

	if [ -e "${KERNEL}" ] && [ -e "${APPEND}" ];then
		LINUX_INSTALL="${LINUX_INSTALL}\nmenuentry \"${LABEL}\" {"
		LINUX_INSTALL="${LINUX_INSTALL}\nlinux\t\t/${KERNEL} ${APPEND} LB_BOOTAPPEND_INSTALL"
		LINUX_INSTALL="${LINUX_INSTALL}\ninitrd\t\t/${INITRD}"
		if [ -n "$DEVICETREE" ];then
			LINUX_INSTALL="${LINUX_INSTALL}\ndevicetree\t\t/${DEVICETREE}"
		fi
		LINUX_INSTALL="${LINUX_INSTALL}\n}"
	fi
}

case "${LB_INITRAMFS}" in
	casper)
		INITFS="casper"
		;;

	live-boot)
		INITFS="live"
		;;

	*)
		INITFS=""
		;;
esac

# Setting destination directory
case "${LB_BINARY_IMAGES}" in
	iso*|tar)
		case "${LB_INITRAMFS}" in
			casper)
				DESTDIR_LIVE="binary/casper"
				;;

			live-boot)
				DESTDIR_LIVE="binary/live"
				;;

			*)
				DESTDIR_LIVE="binary/live"
				;;
		esac

		DESTDIR_INSTALL="binary/install"
		;;

	hdd*|netboot)
		Echo_warning "Bootloader in this image type not yet supported by live-build."
		Echo_warning "This would produce a not bootable image, aborting (FIXME)."
		exit 1
	;;
esac

Check_multiarchitectures

# Creating directory
mkdir -p "${DESTDIR_LIVE}"

# Setting boot parameters
if [ "${LB_UNION_FILESYSTEM}" != "aufs" ]
then
	LB_BOOTAPPEND_LIVE="${LB_BOOTAPPEND_LIVE} union=${LB_UNION_FILESYSTEM}"
fi

if [ -n "${LB_NET_COW_PATH}" ]
then
	Echo_error "Net cow not yet supported on grub"
	exit 1
fi

if [ "${LB_EXPOSED_ROOT}" != "false" ]
then
	LB_BOOTAPPEND_LIVE="${LB_BOOTAPPEND_LIVE} exposedroot"
fi

LB_BOOTAPPEND_LIVE="$(echo ${LB_BOOTAPPEND_LIVE} | sed -e 's|  ||')"

# Assembling kernel configuration

# Default entries
DEFAULT_FLAVOUR="$(echo ${LB_LINUX_FLAVOURS} | awk '{ print $1 }')"
DEFAULT_KERNEL="$(basename chroot/boot/vmlinuz-*${DEFAULT_FLAVOUR})"
DEFAULT_INITRD="initrd.img-$(echo ${DEFAULT_KERNEL} | sed -e 's|vmlinuz-||')"


case ${ARCHITECTURE} in
	'amd64')
		Grub_live_entry "Try ${ORIGIN} without installing" "/casper/vmlinuz" "/casper/initrd.lz" "boot=casper locale=zh_CN quiet splash"
		Grub_live_entry "Install ${ORIGIN}" "/casper/vmlinuz" "/casper/initrd.lz" "boot=casper only-ubiquity locale=zh_CN quiet splash"
		;;
	'arm64')
		Grub_live_entry "Try ${ORIGIN} without installing" "/casper/Image" "/casper/initrd.img" "boot=casper rootwait ro locale=zh_CN KEYBOARDTYPE=pc KEYTABLE=us ignore_uuid quiet splash"
		Grub_live_entry "Install ${ORIGIN}" "/casper/Image" "/casper/initrd.img" "boot=casper only-ubiquity rootwait ro locale=zh_CN KEYBOARDTYPE=pc KEYTABLE=us ignore_uuid quiet splash"
		;;
	'mips64el')
		Grub_live_entry "Try ${ORIGIN} without installing" "/casper/vmlinuz" "/casper/initrd.img" "console=tty1 boot=casper quiet splash loglevel=0 audit=0"
		Grub_live_entry "Install ${ORIGIN}" "/casper/vmlinuz" "/casper/initrd.img" "console=tty1 boot=casper quiet splash loglevel=0 only-ubiquity audit=0"
		;;
	'loongarch64')
		Grub_live_entry "Try ${ORIGIN} without installing" "/casper/vmlinuz" "/casper/initrd.img" "console=ttyS0,115200 boot=casper loglevel=0 audit=0"
		Grub_live_entry "Install ${ORIGIN}" "/casper/vmlinuz" "/casper/initrd.img" "console=ttyS0,115200 boot=casper loglevel=0 only-ubiquity audit=0"
		;;
	'sw64')
		Grub_live_entry "Try ${ORIGIN} without installing" "/casper/vmlinuz" "/casper/initrd.img" "boot=casper loglevel=0 audit=0"
		Grub_live_entry "Install ${ORIGIN}" "/casper/vmlinuz" "/casper/initrd.img" "boot=casper loglevel=0 only-ubiquity audit=0"
		;;
esac

LINUX_LIVE="$(/bin/echo ${LINUX_LIVE} | sed -e 's|binary||g' -e 's|//|/|g')"

# Assembling debian-installer configuration
if [ "${LB_DEBIAN_INSTALLER}" != "false" ]
then
	case ${ARCHITECTURE} in
		'amd64')
		 	LINUX_LIVE="#\t \"Live\"\n${LINUX_LIVE}"
			LINUX_INSTALL="#\t \"Installer\"\n"

			VMLINUZ_DI="install/vmlinuz"
			INITRD_DI="install/initrd.gz"
			APPEND_DI="vga=normal"

			VMLINUZ_GI="install/gtk/vmlinuz"
			INITRD_GI="install/gtk/initrd.gz"
			APPEND_GI="video=vesa:ywrap,mtrr vga=788"

			Grub_install_entry "install" "${VMLINUZ_DI}" "${INITRD_DI}" "${APPEND_DI}"
			Grub_install_entry "installgui" "${VMLINUZ_GI}" "${INITRD_GI}" "${APPEND_GI}"
			Grub_install_entry "expert" "${VMLINUZ_DI}" "${INITRD_DI}" "priority=low ${APPEND_DI}"
			Grub_install_entry "expertgui" "${VMLINUZ_GI}" "${INITRD_GI}" "priority=low ${APPEND_GI}"
			Grub_install_entry "rescue" "${VMLINUZ_DI}" "${INITRD_DI}" "rescue/enable=true ${APPEND_DI}"
			Grub_install_entry "rescuegui" "${VMLINUZ_GI}" "${INITRD_GI}" "rescue/enable=true ${APPEND_GI}"
			Grub_install_entry "auto" "${VMLINUZ_DI}" "${INITRD_DI}" "auto=true priority=critical ${APPEND_DI}"
			Grub_install_entry "autogui" "${VMLINUZ_GI}" "${INITRD_GI}" "auto=true priority=critical ${APPEND_GI}"
			;;
		'arm64')
			LINUX_LIVE="#\t \"Live\"\n${LINUX_LIVE}"
			LINUX_INSTALL="#\t \"Installer\"\n"

			VMLINUZ_DI="install/Image"
			INITRD_DI="install/initrd.img"
                        APPEND_DI="vga=normal rootwait"

                        VMLINUZ_GI="install/gtk/vmlinuz"
                        INITRD_GI="install/gtk/initrd.img"
                        APPEND_GI="video=vesa:ywrap,mtrr vga=788 rootwait"

                        Grub_install_entry "install" "${VMLINUZ_DI}" "${INITRD_DI}" "${APPEND_DI}"
                        Grub_install_entry "installgui" "${VMLINUZ_GI}" "${INITRD_GI}" "${APPEND_GI}"
                        Grub_install_entry "expert" "${VMLINUZ_DI}" "${INITRD_DI}" "priority=low ${APPEND_DI}"
                        Grub_install_entry "expertgui" "${VMLINUZ_GI}" "${INITRD_GI}" "priority=low ${APPEND_GI}"
                        Grub_install_entry "rescue" "${VMLINUZ_DI}" "${INITRD_DI}" "rescue/enable=true ${APPEND_DI}"
                        Grub_install_entry "rescuegui" "${VMLINUZ_GI}" "${INITRD_GI}" "rescue/enable=true ${APPEND_GI}"
                        Grub_install_entry "auto" "${VMLINUZ_DI}" "${INITRD_DI}" "auto=true priority=critical ${APPEND_DI}"
                        Grub_install_entry "autogui" "${VMLINUZ_GI}" "${INITRD_GI}" "auto=true priority=critical ${APPEND_GI}"
			;;
	esac
fi

LINUX_INSTALL="$(/bin/echo ${LINUX_INSTALL} | sed -e 's|binary||g' -e 's|//|/|g')"

# Assembling memtest configuration
if [ -f "${DESTDIR_LIVE}"/memtest ]
then
	MEMTEST="#\t \"Other\"\n"
	MEMTEST="${MEMTEST}\nmenuentry\t\"${LB_MEMTEST}\" {\nlinux16\t$(basename ${DESTDIR_LIVE})/memtest\n}"
	MEMTEST="$(/bin/echo ${MEMTEST} | sed -e 's|//|/|g')"
fi

# Copying templates
mkdir -p binary/boot/grub
cp -r "${TEMPLATES}"/* binary/boot/grub

case ${LB_BINARY_IMAGES} in
	iso*)
		case ${ARCHITECTURE} in
			'amd64')
				FILES="chroot/usr/lib/grub/x86_64-efi chroot/usr/share/grub/*.pf2"
				;;
			'arm64'|'mips64el')
				FILES="chroot/usr/lib/grub/${ARCHITECTURE}-efi chroot/usr/share/grub/*.pf2"
				;;
			'loongarch64')
				FILES="chroot/usr/lib/grub/${ARCHITECTURE}-efi"
				;;
			'sw64')
				FILES="chroot/usr/lib/grub/${ARCHITECTURE}-efi"
				;;
			esac
                ;;
esac

# Copying grub
cp -r ${FILES} binary/boot/grub

if [ "${LB_BUILD_WITH_CHROOT}" = "false" ]
then
	FILES="$(echo ${FILES} | sed -e 's|chroot||g')"
fi

# Copying local configuration file
if [ -f config/binary_grub/grub.cfg ]
then
	cp config/binary_grub/grub.cfg binary/boot/grub/grub.cfg
fi

sed -i -e "s|LINUX_LIVE|${LINUX_LIVE}|" -e "s|LINUX_INSTALL|${LINUX_INSTALL}|" -e "s|MEMTEST|${MEMTEST}|" binary/boot/grub/grub.cfg
sed -i -e "s|LB_BOOTAPPEND_INSTALL|${LB_BOOTAPPEND_INSTALL}|" -e "s|LB_BOOTAPPEND_LIVE|${LB_BOOTAPPEND_LIVE}|" binary/boot/grub/grub.cfg

sed -i -e 's|\ $||g' binary/boot/grub/grub.cfg

#kylin create efi.img
KY_EFI=""
KY_EFI_NAME=""
GRUB_MODS="ext2 fat part_msdos part_gpt search_fs_uuid search_label search_fs_file search normal linux font all_video reboot configfile test iso9660"

if [ -d chroot/usr/lib/grub/x86_64-efi ];then
    KY_EFI="/usr/lib/grub/x86_64-efi"
    KY_EFI_NAME="x86_64-efi"
    KY_BOOT_EFI_NAME="BOOTX64.EFI"
    KY_GRUB_EFI_NAME="grubx64.efi"
	GRUB_MODS="${GRUB_MODS} linuxefi"
elif  [ -d chroot/usr/lib/grub/arm64-efi ];then
    KY_EFI="/usr/lib/grub/arm64-efi"
    KY_EFI_NAME="arm64-efi"
    KY_BOOT_EFI_NAME="BOOTAA64.EFI"
    KY_GRUB_EFI_NAME="grubaa64.efi"
elif  [ -d chroot/usr/lib/grub/mips64el-efi ];then
    KY_EFI="/usr/lib/grub/mips64el-efi"
    KY_EFI_NAME="mips64el-efi"
    KY_BOOT_EFI_NAME="BOOTMIPS.EFI"
    KY_GRUB_EFI_NAME="grubmips64.efi"
elif  [ -d chroot/usr/lib/grub/loongarch64-efi ];then
    KY_EFI="/usr/lib/grub/loongarch64-efi"
    KY_EFI_NAME="loongarch64-efi"
    KY_BOOT_EFI_NAME="BOOTLOONGARCH.EFI"
    KY_GRUB_EFI_NAME="grubloongarch64.efi"
elif  [ -d chroot/usr/lib/grub/sw64-efi ];then
    KY_EFI="/usr/lib/grub/sw64-efi"
    KY_EFI_NAME="sw64-efi"
    KY_BOOT_EFI_NAME="BOOTLOONGARCH.EFI"
    KY_GRUB_EFI_NAME="grubsw64.efi"
fi

mkdir -p binary/boot/grub
if [ -n "${KY_EFI}" ];then
        cat > kylin_efi.sh << EOF
input_efi_dir=${KY_EFI}
core_efi_img=\$(mktemp)
efi_mount_tmp=\$(mktemp -d)
grub-mkimage -p /boot/grub -o \${core_efi_img} -O ${KY_EFI_NAME} -d \${input_efi_dir} ${GRUB_MODS}
dd if=/dev/zero of=efi.img bs=1M count=28
mkfs.fat -F12 efi.img
mount -o loop efi.img \${efi_mount_tmp}
mkdir -p \${efi_mount_tmp}/EFI/BOOT/
cp \${core_efi_img} \${efi_mount_tmp}/EFI/BOOT/${KY_BOOT_EFI_NAME}
cp \${core_efi_img} \${efi_mount_tmp}/EFI/BOOT/${KY_GRUB_EFI_NAME}
cp -r \${efi_mount_tmp}/EFI binary/
umount \${efi_mount_tmp}
rm -rf \${efi_mount_tmp}
rm -rf \${core_efi_img}
cp -rf \${input_efi_dir} binary/boot/grub
mv efi.img binary/boot/grub/
EOF

	case "${LB_BUILD_WITH_CHROOT}" in
        	true)
                	# Moving image
                	mv kylin_efi.sh chroot
                	mv binary chroot

	                Chroot chroot "sh kylin_efi.sh"

	                # Move image
        	        mv chroot/binary ./
	                ;;

        	false)
	                sh kylin_efi.sh
                	;;
	esac
fi

if [ -f chroot/boot/grub/grub_ba.efi ];then
        cp chroot/boot/grub/grub_ba.efi binary/boot/grub/
fi

if [ -f chroot/boot/grub/grub_kl.efi ];then
        cp chroot/boot/grub/grub_kl.efi binary/boot/grub/
fi
#end


# Saving cache
Save_cache cache/packages.binary

# Creating stage file
Create_stagefile .build/binary_grub2_efi
