#!/bin/ash

do_exit() {
	[ "$VFAT_LIST" ] && [ -f "$VFAT_LIST" ] && rm "$VFAT_LIST"
	[ "$TMP_LIST" ] && [ -f "$TMP_LIST" ] && rm "$TMP_LIST"
	[ "$TMP_BLK" ] && [ -f "$TMP_BLK" ] && rm "$TMP_BLK"
	[ "$CACHE_FN" ] && [ -f "$CACHE_FN" ] && rm "$CACHE_FN"
	while IFS='' read ONE_MP; do
		umount "$ONE_MP" 2>/dev/null
	done < "$MNTD_FN"
	rm -f "$MNTD_FN"
	if [ "$1" ]; then
		yad $YAD_STD_OPTS --title "DiskPup v${VER}" --width=220 --text-align=center \
			--text "<big>${1}</big>" \
			--button=gtk-ok:0
	fi
	exit $2
}

error_exit() {
	do_exit "$1" 1
}

normal_exit() {
	do_exit "$1" 0
}

# check Grub2 uefi and mbr
grub2_chk() {
	EFI_TAR="$(find $EXE_DIR -name '*-efi.tar.xz' | head -n1)"
	[ "$EFI_TAR" ] || error_exit "grub2-efi support missing"
	MBR_TAR="$(find $EXE_DIR -name '*-mbr.tar.xz' | head -n1)"
	[ "$MBR_TAR" ] || error_exit "grub2-mbr support missing"
}

boot_part_chk() {
	VFAT_LIST="/tmp/${0##*/}_$$_vfat_list.txt"
	[ -f "$VFAT_LIST" ] && rm "$VFAT_LIST"
	grep 'vfat' "$TMP_BLK" |
	while IFS='' read ONE_LINE; do
		DRV="${ONE_LINE%%:*}"; DRV="${DRV#/dev/}"
		DRV_ONE="${DRV%[0-9]}"; DRV_ONE="${DRV_ONE%[0-9]}"; DRV_ONE="${DRV_ONE%[0-9]}"
		DRV_ONE="${DRV_ONE}1"
		[ "$DRV" = "$DRV_ONE" ] || continue
		LAB="${ONE_LINE#*LABEL=\"}"
		[ "${LAB:0:1}" = "/" ] && LAB='' || LAB="${LAB%%\"*}"
		echo "$DRV" >> "$VFAT_LIST"
		echo "$LAB" >> "$VFAT_LIST"
	done
	[ -s "$VFAT_LIST" ] || error_exit "No suitable fat32 partitions found.
They must be the first partition on the disk."
}

get_boot_type() {
	BOOT_TYPE='both'
	get_device "$DEST_PART"
	if [ "$get_device_RET" ]; then
		[ "$(parted "/dev/$get_device_RET" print 2>/dev/null | grep 'gpt')" ] && BOOT_TYPE='uefi'
	fi
}

get_boot_part() {
	DEST_SPEC="$(yad $YAD_STD_OPTS --title "DiskPup v${VER} - Boot partition" \
		--text "This script updates the selected boot partition,
with files needed to boot the Puppy frugal install in,
<span foreground='purple'>$SFS_PART:$SFS_DIR</span>.

<span foreground='red'>Will overwrite boot files on the selected partition.</span>

Select a fat32 boot partition:" \
		--list --print-column=1 --column=Partition --column=Label < $VFAT_LIST)"
	[ $? -eq 0 ] || error_exit
	rm "$VFAT_LIST"
	[ "$DEST_SPEC" ] || error_exit "No partition selected."
	DEST_PART="${DEST_SPEC%%|*}"

	ensure_mounted "$DEST_PART"
	[ "$ensure_mounted_DID" ] && echo "$ensure_mounted_MP" >> "$MNTD_FN"
	[ "$ensure_mounted_MP" ] || error_exit "Could not mount \"$DEST_PART\"."
	DEST_MP="$ensure_mounted_MP"
	if [ -d "$DEST_MP/EFI/Microsoft" ]; then
		HAVE_WIN_BOOT='yes'
	else
		HAVE_WIN_BOOT=''
	fi
	[ "$DEST_MTD" ] && umount "$DEST_MP" 2>/dev/null
	if [ "$HAVE_WIN_BOOT" ]; then
		yad $YAD_STD_OPTS --title "DiskPup v${VER}" --width=500 \
			--text "<big>The <span foreground='purple'>$DEST_PART</span> partition already contains a Windows UEFI boot.
Continuing with this install could damage this boot facility.

It is recommended that you click <span foreground='blue'>Cancel</span>, to abort this install.
Then choose a different fat32 partition. A usb stick would do.</big>"
		[ $? -eq 0 ] || error_exit
	fi
}

get_install_location() {
	TMP_LIST="/tmp/${0##*/}_$$_tmp_list.txt"
	[ -f "$TMP_LIST" ] && rm "$TMP_LIST"
	while read ONE_LINE; do
		TYPE="${ONE_LINE#*TYPE=\"}"
		[ "${TYPE:0:1}" = "/" ] && TYPE='' || TYPE="${TYPE%%\"*}"
		[ "$TYPE" = "crypto_LUKS" ] && continue
		get_part_fs_class "$TYPE"
		[ "$get_part_fs_class_RET" = "cd" ] && continue
		DRV="${ONE_LINE%%:*}"; DRV="${DRV#/dev/}"
		LAB="${ONE_LINE#*LABEL=\"}"
		[ "${LAB:0:1}" = "/" ] && LAB='' || LAB="${LAB%%\"*}"
		[ "$LAB" = "System Reserved" ] && continue
		[ "$LAB" = "" -a "$TYPE" = "ntfs" ] && continue
		echo "$DRV" >> "$TMP_LIST"
		echo "$TYPE" >> "$TMP_LIST"
		echo "$LAB" >> "$TMP_LIST"
	done < "$TMP_BLK"

	if [ -s "$TMP_LIST" ]; then
		SFS_SPEC="$(yad $YAD_STD_OPTS --title "DiskPup v${VER} - Puppy partition" --width=300 --height=200 \
			--text "Select a partition to contain Puppy:" \
			--list --column=Part --column=Type --column=Label < $TMP_LIST)"
		[ $? -eq 0 ] || error_exit
		rm "$TMP_LIST"
		if [ "$SFS_SPEC" ]; then
			SFS_PART="${SFS_SPEC%%|*}"
		else
			error_exit "No partition selected."
		fi
	else
		error_exit "No suitable partitions found."
	fi

	ensure_mounted "$SFS_PART"
	[ "$ensure_mounted_DID" ] && echo "$ensure_mounted_MP" >> "$MNTD_FN"
	[ "$ensure_mounted_MP" ] || error_exit "Could not mount \"$SFS_PART\"."
	SFS_MP="$ensure_mounted_MP"

	INSTL_DIR="$(yad $YAD_STD_OPTS --title "DiskPup v${VER} - Puppy directory" \
		--file --directory --width=600 --height=460 \
		--text " <span foreground='purple'>$SFS_PART</span> is mounted at <span foreground='purple'>$SFS_MP</span>.

 Select the directory that will contain the Puppy frugal install.

 Note: If you use the <span foreground='blue'>Create Folder</span> button,
 you need to hit the <span foreground='purple'>Enter</span> key after typing the new folder name.
" \
		--filename="$SFS_MP/")"
	[ $? -eq 0 ] || error_exit
#	[ -d "$INSTL_DIR" ] || error_exit "No install directory selected."

	DIR_MP="$(stat -Lc %m "$INSTL_DIR")"
	if [ "$DIR_MP" != "$SFS_MP" ]; then
		SFS_PART="$(grep -m1 "$DIR_MP" /proc/mounts | cut -f1 -d' ')"
		SFS_PART="${SFS_PART#/dev/}"
		SFS_MP="$DIR_MP"
	fi

	INSTALL_DIR="$(realpath "$INSTL_DIR")"
	if [ "$SRC_TYPE" = "directory" ]; then
		#check that INSTALL_DIR is not the same as SRC_DIR
		[ "$INSTALL_DIR" = "$(realpath "$SRC_DIR")" ] && error_exit "Source directory:
  <span foreground='purple'>$SRC_DIR</span>
Destination directory:
  <span foreground='purple'>$INSTL_DIR</span>
These are the same directory."
	fi
	SFS_DIR="${INSTALL_DIR#${SFS_MP}}"
}

get_source_location() {
	SRC_SPEC="$(yad $YAD_STD_OPTS --title "DiskPup v${VER} - Source type" --height=240 \
		--text "DiskPup installs a single Puppy.

A directory is required to contain Puppy.
A <span foreground='purple'>fat32</span> partition is required for Grub2.
The <span foreground='purple'>fat32</span> partition must be the first on it's drive.
 
Select the source type:" \
		--list --no-headers --print-column=3 --radiolist --column=:RD --column=:TXT --column=:TXT \
		TRUE '    ' 'iso' FALSE '    ' 'zip' FALSE '    ' 'directory' FALSE '    ' 'this')"
	[ $? -eq 0 ] || error_exit
	SRC_TYPE="${SRC_SPEC%%|*}"
	SRC_DIR=''; SRC_FN=''
	if [ "$SRC_TYPE" = "this" ]; then
		. /etc/rc.d/PUPSTATE
		#mainly to catch unplugged usb devices, but doing it for all
		for ONE_PARM in $(head -n1 /proc/cmdline); do
			case $ONE_PARM in
				psfspart=*) PSFSID="${ONE_PARM#*=}"; break ;;
				pdrv=*) PSFSID="${ONE_PARM#*=}"; break ;;
				pupsfs=*) PSFSID="${ONE_PARM#*=}"; break ;;
				pdev1=*) PSFSID="${ONE_PARM#*=}"; break ;;
			esac
		done
		if [ "$PSFSID" ]; then
			ID_PART="$(grep "=\"${PSFSID}\"" "$TMP_BLK" | cut -f1 -d':')"
			[ "$ID_PART" ] || error_exit "Puppy install partition is not available.
Probably due to unplugged usb boot device."
			SRC_PART="${ID_PART#/dev/}"
		else
			SRC_PART="${PUPSFS%%,*}"
		fi
		ensure_mounted "$SRC_PART"
		[ "$ensure_mounted_DID" ] && echo "$ensure_mounted_MP" >> "$MNTD_FN"
		[ "$ensure_mounted_MP" ] || error_exit "Could not mount \"$SRC_PART\"."
		SRC_MP="$ensure_mounted_MP"
		SFS_FN="${SRC_MP}${PUPSFS##*,}"
		if [ -f "$SFS_FN" ]; then
			SRC_DIR="${SFS_FN%/*}"
			SRC_TYPE='directory'
		else
			error_exit "Puppy file \"$SFS_FN\" not found."
		fi
	elif [ "$SRC_TYPE" = "directory" ]; then
		SRC_DIR="$(yad $YAD_STD_OPTS --title "DiskPup v${VER} - Source directory" \
			--file --directory --width=600 --height=460 \
			--text " Select the directory containing the Puppy files." \
			--filename="/mnt/")"
		[ $? -eq 0 ] || error_exit
		SFS_FN="$(find "$SRC_DIR" -maxdepth 1 -type f -name 'puppy_*.sfs')"
		[ "$SFS_FN" ] || error_exit "No Puppy files found in $SRC_DIR."
	else
		SRC_FN="$(yad $YAD_STD_OPTS --title "DiskPup v${VER} - Source file" \
			--file --file-filter "$SRC_TYPE files | *.$SRC_TYPE" --width=600 --height=460 \
			--text " Select the $SRC_TYPE file containing the Puppy files." \
			--filename="$HOME/")"
		[ $? -eq 0 ] || error_exit
		[ -d "$SRC_FN" ] && error_exit "No $SRC_TYPE file selected."
		[ "${SRC_FN##*.}" = "$SRC_TYPE" ] || error_exit "No $SRC_TYPE file selected."
	fi
}

confirm_choices() {
	if [ "$SRC_FN" ]; then
		SRC_DISP="$SRC_FN"
	else
		SRC_DISP="$SRC_DIR"
	fi
	if [ "$BOOT_TYPE" = "both" ]; then
		TYPE_DISP="Supporting <span foreground='purple'>uefi</span> and <span foreground='purple'>mbr</span> boots."
	else
		TYPE_DISP="Supporting <span foreground='purple'>uefi</span> boots."
	fi
	if [ "$SFS_DIR" ]; then
		SFS_DISP="$SFS_PART:$SFS_DIR"
	else
		SFS_DISP="$SFS_PART"
	fi
	yad $YAD_STD_OPTS --title "DiskPup v${VER} - confirm" --width=260 \
		--text "About to install Puppy files from
<span foreground='purple'>$SRC_DISP</span>
into <span foreground='purple'>$SFS_DISP</span>.

And install Grub2 boot files into <span foreground='purple'>$DEST_PART</span>.
$TYPE_DISP

Click <span foreground='blue'>OK</span> to continue."
	[ $? -eq 0 ] || error_exit
}

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

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

MNTD_FN="/tmp/frugalpup_$$_did_mount.txt"
[ -f "$MNTD_FN" ] && rm -f "$MNTD_FN"

DRV_NAME=''
BOOT_TYPE=''
SRC_TYPE=''
SRC_DIR=''
SRC_PART=''

grub2_chk

[ -f "$UTILS_DIR/functions_part" ] || error_exit "File <span foreground='purple'>$UTILS_DIR/functions_part</span> not found."
. "$UTILS_DIR/functions_part"

TMP_BLK="/tmp/${0##*/}_$$_blk_list.txt"
busybox blkid | grep -v 'squashfs' | grep -v 'swap' | grep -v 'zram' | sort > "$TMP_BLK"

boot_part_chk

get_source_location
get_install_location

get_boot_part
get_boot_type

confirm_choices

[ -f "$CONFIG_FN" ] && . "$CONFIG_FN"

echo "SRC_TYPE='$SRC_TYPE'" > "$CACHE_FN"
echo "SRC_FN='$SRC_FN'" >> "$CACHE_FN"
echo "SRC_DIR='$SRC_DIR'" >> "$CACHE_FN"
echo "SFS_PART='$SFS_PART'" >> "$CACHE_FN"
echo "SFS_DIR='$SFS_DIR'" >> "$CACHE_FN"
echo "XTRA_PARMS='$minPARMS'" >> "$CACHE_FN"
ERR_MSG="$("$EXE_DIR/frugalpup-dopupdir")"
[ $? -eq 0 ] || error_exit "frugalpup-dopupdir: $ERR_MSG"

echo "SFS_PART='$SFS_PART'" > "$CACHE_FN"
echo "SFS_DIR='$SFS_DIR'" >> "$CACHE_FN"
echo "DEST_PART='$DEST_PART'" >> "$CACHE_FN"
echo "BOOT_TYPE='$BOOT_TYPE'" >> "$CACHE_FN"
ERR_MSG="$("$EXE_DIR/frugalpup-dobootpart")"
[ $? -eq 0 ] || error_exit "frugalpup-dobootpart: $ERR_MSG"

if [ "$SFS_DIR" ]; then
	EX_SFS="$SFS_PART:$SFS_DIR"
else
	EX_SFS="$SFS_PART"
fi
normal_exit "Puppy installed in <span foreground='purple'>$EX_SFS</span>
and booting from <span foreground='purple'>$DEST_PART</span>."
