#!/bin/ash

error_exit() {
	[ "$1" ] && echo "$1"
	[ "$DID_MOUNT" ] && umount "$BOOT_MP"
	exit 1
}

write_line() {
	if [ "$2" ]; then
		echo "$1" >> "$2"
	else
		echo "$1"
	fi
}

EXE_DIR="$(dirname $(readlink -f ${0}))"
COMN_FN="$EXE_DIR/frugalpup-common"
[ -f "$COMN_FN" ] && . "$COMN_FN"

if [ $# -lt 1 -o "$1" = "-h" -o "$1" = "--help" ]; then
	SHBASE="`basename $0`"
	SHBASE="${SHBASE#*-}"
	echo "${SHBASE} v${VER}"
	echo "Generate Puppy boot config file entry/entries like FrugalPup."
	echo ""
	echo "Usage: $SHBASE  install-directory [boot-type] [output-directory]"
	echo "If <install-directory> is the parent of a number of installs,"
	echo "    many boot enties will be generated."
	echo "<boot-type> can be \"g4dos|grub2|fs\"."
	echo "if <boot-type> is omitted, \"grub2\" is assumed."
	echo "if <boot-type> is \"fs\", then a \"grub2\" \"insmod\" for the fs-type, is included."
	echo "If <output-directory> is specified,"
	echo "    the entries will be appended to \"grub.cfg\""
	echo "    or \"menu.lst\" in that directory."
	echo "If <output-directory> is not specified,"
	echo "    the entries will be written to STDOUT, usually displayed on the console."
	echo ""
	echo "Examples:"
	echo " $SHBASE /mnt/home/puppy/tahr"
	echo " $SHBASE /mnt/home/puppy/tahr fs"
	echo " $SHBASE /mnt/home/puppy/tahr g4dos"
	echo " $SHBASE /mnt/home/puppy /mnt/sdc1"
	echo " $SHBASE /mnt/home/puppy fs /mnt/sdc1"
	echo " $SHBASE /mnt/home/puppy g4dos /mnt/sdc1"
	exit 1
fi

#set -x; exec &> /tmp/frugalpup-bootentry.log

[ -f "$UTILS_DIR/functions_part" ] || error_exit "File \"${UTILS_DIR}/functions_part\" not found."
. "$UTILS_DIR/functions_part"

[ -d "$1" ] || error_exit "Directory \"$1\" not found."

PUPS="$(find "$1" -maxdepth 2 -type f -name 'puppy_*.sfs' | sort)"
[ "$PUPS" ] || error_exit "No Puppy frugal installs found in \"$1\"."
shift

DO_GRUB2='yes'
DO_G4DOS=''; DO_FS=''
if [ "$1" ]; then
	case "$1" in
		grub2)
			DO_GRUB2='yes'
			shift
			;;
		g4dos)
			DO_G4DOS='yes'
			DO_GRUB2=''
			shift
			;;
		grub4dos)
			DO_G4DOS='yes'
			DO_GRUB2=''
			shift
			;;
		modules)
			DO_FS='yes'
			shift
			;;
		fs)
			DO_FS='yes'
			shift
			;;
		*)
			[ -d "$1" ] || error_exit "\"$1\" is not a valid boot-type."
			;;
	esac
fi

REDIR_M=''; REDIR_G=''
if [ "$1" ]; then
	REDIR_M="${1}/menu.lst"
	REDIR_G="${1}/grub.cfg"
fi

DID_MOUNT=''

# add TZ boot parameter from running system
TZspec=''
if [ -x "$UTILS_DIR/timezone-tz" ]; then
	P_TZ="$("$UTILS_DIR/timezone-tz")"
	[ "$P_TZ" ] && TZspec=" TZ=$P_TZ"
fi

FIRST='yes'
for ONE_PUP in $PUPS; do
	if [ "$FIRST" ]; then
		FIRST=''
		SRC_MP="$(stat -Lc %m $ONE_PUP)"
		SRC_PART="$(grep "$SRC_MP" /proc/mounts | cut -f1 -d' ')"; SRC_PART="${SRC_PART#/dev/}"
		get_device "$SRC_PART"
		P_MEDIA1='ata'
		[ "$(probedisk -type "/dev/$get_device_RET" | grep 'usb')" ] && P_MEDIA1='usb'
		P_MEDIA2='hd'
		if [ -f /sys/block/$get_device_RET/removable ]; then
			read REMOV < /sys/block/$get_device_RET/removable
			[ "$REMOV" = "1" ] && P_MEDIA2='flash'
		fi
		if [ -f /sys/block/$get_device_RET/queue/rotational ]; then
			read ROTATE < /sys/block/$get_device_RET/queue/rotational
		fi
		BLK_LINE="$(blkid /dev/$SRC_PART)"
		SRC_LABEL="${BLK_LINE#*LABEL=\"}"
		[ "${SRC_LABEL:0:1}" = "/" ] && SRC_LABEL='' || SRC_LABEL="${SRC_LABEL%%\"*}"
		SRC_UUID="${BLK_LINE#*UUID=\"}"
		[ "${SRC_UUID:0:1}" = "/" ] && SRC_UUID='' || SRC_UUID="${SRC_UUID%%\"*}"
		SRC_TYPE="${BLK_LINE#*TYPE=\"}"
		[ "${SRC_TYPE:0:1}" = "/" ] && SRC_TYPE='' || SRC_TYPE="${SRC_TYPE%%\"*}"
		[ "$SRC_TYPE" = "f2fs" ] && P_MEDIA2='hd'
		GRUB_MOD=''
		if [ "$DO_GRUB2" ]; then
			if [ "$DO_FS" ]; then
				if [ "$SRC_TYPE" ]; then
					case $SRC_TYPE in
						ext4) GRUB_MOD='ext2' ;;
						ext3) GRUB_MOD='ext2' ;;
						vfat) GRUB_MOD='fat' ;;
						*) GRUB_MOD="$SRC_TYPE" ;;
					esac
				fi
			fi
		fi
	fi
	PUP_DIR="$(realpath ${ONE_PUP%/*})"; PUP_SUB="${PUP_DIR#${SRC_MP}}"
	PUP_VER="${ONE_PUP##*/}"; PUP_VER="${PUP_VER#puppy_}"; PUP_VER="${PUP_VER%.sfs}"
	PSAVEID=''; PSAVEDIR=''; PSAVEMARK=''; SAVEspec=''; SUBspec=''; PKNLPARMS=''; PFIXPARMS=''; PARMSspec=''; PFIXspec=''
	[ -s "$PUP_DIR/SAVEMARK" ] && read PSAVEMARK < "$PUP_DIR/SAVEMARK"
	[ -s "$PUP_DIR/$PARMS_FN" ] && . "$PUP_DIR/$PARMS_FN"
	[ "$PSAVEMARK" ] && SAVEspec=" psavemark=${PSAVEMARK}"
	[ "$PKNLPARMS" ] && PARMSspec=" ${PKNLPARMS}"
	[ "$PFIXPARMS" ] && PFIXspec=" pfix=${PFIXPARMS}"
	if [ "$ROTATE" != "0" -a "$PSAVEID" ]; then 
		BLK_LINE="$(busybox blkid | grep "$PSAVEID")"
		SAVE_PART="${BLK_LINE%%:*}"; SAVE_PART="${SAVE_PART#/dev/}"
		get_device "$SAVE_PART"
		if [ -f /sys/block/$get_device_RET/queue/rotational ]; then
			read ROTATE < /sys/block/$get_device_RET/queue/rotational
		fi
	fi
	ISMI=''
	[ "$(find "$PUP_DIR" -maxdepth 1 -type f -name "mio*_${PUP_VER}.sfs")" ] && ISMI='yes'
	if [ "$ISMI" = "" ]; then
		[ "$(find "$PUP_DIR" -maxdepth 1 -type f -name "mia*_${PUP_VER}.sfs")" ] && ISMI='yes'
	fi
	if [ "$ISMI" = "" ]; then
		[ "$(find "$PUP_DIR" -maxdepth 1 -type f -name 'overlay_mods*.sfs')" ] && ISMI='yes'
	fi
	if [ "$ISMI" ]; then
		get_part_fs_class "$SRC_TYPE"
		if [ "$get_part_fs_class_RET" = "linux" ]; then
			if [ -f "$PUP_DIR/initrd.gz" ]; then
				ISMI=''
			fi
		fi
	fi
	if [ "$ISMI" ]; then
		SFS_PART_BPN='psfspart'
		[ "$PUP_SUB" ] && SUBspec=" psfsdir=${PUP_SUB}"
		if [ "$PFIXspec" = "" ]; then
			if [ "$ROTATE" = "0" ]; then
				PFIXspec=' pfix=trim'
			else
				PFIXspec=''
			fi
		fi
		if [ "$PSAVEID" ]; then
			SAVEspec=" psavepart=${PSAVEID}"
			[ "$PSAVEDIR" ] && SAVEspec="${SAVEspec} psavedir=${PSAVEDIR}"
		fi
	else
		SFS_PART_BPN='pdrv'
		[ "$PUP_SUB" ] && SUBspec=" psubdir=${PUP_SUB}"
		if [ "$PFIXspec" = "" ]; then
			if [ "$ROTATE" = "0" ]; then
				PFIXspec=' pfix=fsck,fsckp,trim'
			else
				PFIXspec=' pfix=fsck,fsckp'
			fi
		fi
		if [ "$PSAVEID" ]; then
			SAVEspec=" psave=${PSAVEID}"
			[ "$PSAVEDIR" ] && SAVEspec="${SAVEspec}:${PSAVEDIR}/"
		fi
	fi
	INITRD_FN=''
	if [ "$ISMI" ]; then
		[ -f "$PUP_DIR/mio_initrd.gz" ] && INITRD_FN='mio_initrd.gz'
		if [ "$INITRD_FN" = "" ]; then
			[ -f "$PUP_DIR/mia_initrd.gz" ] && INITRD_FN='mia_initrd.gz'
		fi
	fi
	[ "$INITRD_FN" ] || INITRD_FN='initrd.gz'
	[ "$PUP_VER" = "upupbb_19.03" ] && PUP_VER='bionicpup32_8.0'
	if [ "$DO_GRUB2" ]; then
		write_line "menuentry \"Puppy ${PUP_VER/_/ }\" {" "$REDIR_G"
		if [ "$DO_FS" ]; then
			[ "$GRUB_MOD" ] && write_line "    insmod $GRUB_MOD" "$REDIR_G"
		fi
		write_line "    search --no-floppy --fs-uuid --set  $SRC_UUID" "$REDIR_G"
		write_line "    echo \"Loading vmlinuz\"" "$REDIR_G"
		if [ "$SRC_LABEL" ]; then
			write_line "    linux $PUP_SUB/vmlinuz${PARMSspec} pmedia=${P_MEDIA1}${P_MEDIA2} ${SFS_PART_BPN}=${SRC_LABEL}${SUBspec}${SAVEspec}${PFIXspec}${TZspec}" "$REDIR_G"
		else
			write_line "    linux $PUP_SUB/vmlinuz${PARMSspec} pmedia=${P_MEDIA1}${P_MEDIA2} ${SFS_PART_BPN}=${SRC_UUID}${SUBspec}${SAVEspec}${PFIXspec}${TZspec}" "$REDIR_G"
		fi
		write_line "    echo \"Loading $INITRD_FN\"" "$REDIR_G"
		write_line "    initrd $PUP_SUB/$INITRD_FN" "$REDIR_G"
		write_line "}" "$REDIR_G"
	fi
	if [ "$DO_G4DOS" ]; then
		write_line "title Puppy ${PUP_VER/_/ }" "$REDIR_M"
		write_line "    find --set-root --ignore-floppies uuid () $SRC_UUID" "$REDIR_M"
		if [ "$SRC_LABEL" ]; then
			write_line "    kernel $PUP_SUB/vmlinuz${PARMSspec} pmedia=${P_MEDIA1}${P_MEDIA2} ${SFS_PART_BPN}=${SRC_LABEL}${SUBspec}${SAVEspec}${PFIXspec}${TZspec}" "$REDIR_M"
		else
			write_line "    kernel $PUP_SUB/vmlinuz${PARMSspec} pmedia=${P_MEDIA1}${P_MEDIA2} ${SFS_PART_BPN}=${SRC_UUID}${SUBspec}${SAVEspec}${PFIXspec}${TZspec}" "$REDIR_M"
		fi
		write_line "    initrd $PUP_SUB/$INITRD_FN" "$REDIR_M"
		write_line "" "$REDIR_M"
	fi
done

[ "$DID_MOUNT" ] && umount "$BOOT_MP"

exit 0
