#!/bin/ash

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

error_exit() {
	do_exit "$1" 1
}

normal_exit() {
	do_exit "$1" 0
}

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

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

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

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

SFS_PART=''; SFS_DIR=''; SFS_LABEL=''
[ "$CACHE_FN" ] && [ -f "$CACHE_FN" ] && . "$CACHE_FN"

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

SRC_TYPE='';SRC_DIR=''; SRC_FN=''
SRC_SPEC="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Source type" --height=150 \
	--text "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%%|*}"

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 "FrugalPup-puppyfiles 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 "FrugalPup-puppyfiles 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."
fi

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
	if [ "$SFS_PART" ]; then
		TMSG="<span foreground='purple'>$SFS_PART</span> is the default partition to contain Puppy.
Simply click <span foreground='blue'>OK</span> to use it,
Or,
select another partition to contain Puppy:"
		THT=240
	else
		TMSG="Select a partition to contain Puppy:"
		THT=200
	fi
	DEST_SPEC="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Destination partition" --width=300 --height=$THT \
		--text "$TMSG" \
		--list --column=Part --column=Type --column=Label < $TMP_LIST)"
	[ $? -eq 0 ] || error_exit
	rm "$TMP_LIST"
	if [ "$DEST_SPEC" ]; then
		DEST_PART="${DEST_SPEC%%|*}"
	elif [ "$SFS_PART" ]; then
		DEST_PART="$SFS_PART"
	else
		error_exit "No partition selected."
	fi
else
	error_exit "No suitable partitions found."
fi

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"

get_part_id "$DEST_PART"
DEST_ID="$get_part_id_RET"

DEST_DIR="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Puppy directory." \
	--file --directory --width=600 --height=500 \
	--text " <span foreground='purple'>$DEST_PART</span> is mounted at <span foreground='purple'>$DEST_MP</span>.

 Select a directory to contain the Puppy frugal install files.

 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="${DEST_MP}${SFS_DIR%/*}/")"
[ $? -eq 0 ] || error_exit

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

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

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

SAVE_PART=''; SAVE_DIR=''
PKNLPARMS=''; PFIXPARMS=''; PSAVEID=''; PSAVEMARK=''
[ -f "$DEST_DIR/$PARMS_FN" ] && . "$DEST_DIR/$PARMS_FN"

if [ "$PSAVEID" ]; then
	SAVE_DEV="$(grep "$PSAVEID" "$TMP_BLK" | cut -d':' -f1)"
	if [ "$SAVE_DEV" ]; then
		SAVE_PART="${SAVE_DEV#/dev/}"
		SAVE_DIR="$PSAVEDIR"
		SAVE_ID="$PSAVEID"
	fi
elif [ "$PSAVEMARK" ]; then
	SAVE_DEV="${DEST_PART%[0-9]}"; SAVE_DEV="${SAVE_DEV%[0-9]}"; SAVE_DEV="${SAVE_DEV%[0-9]}"
	SAVE_PART="${SAVE_DEV}${PSAVEMARK}"
	SAVE_DIR="$SFS_DIR"
	SAVE_ID="$DEST_ID"
fi

if [ "$showSAVE" ]; then
	[ -f "$TMP_LIST" ] && rm "$TMP_LIST"
	while read ONE_LINE; do
		TYPE="${ONE_LINE#*TYPE=\"}"
		[ "${TYPE:0:1}" = "/" ] && TYPE='' || TYPE="${TYPE%%\"*}"
		get_part_fs_class "$TYPE"
		[ "$get_part_fs_class_RET" = "linux" ] || continue
		DRV="${ONE_LINE%%:*}"; DRV="${DRV#/dev/}"
		LAB="${ONE_LINE#*LABEL=\"}"
		[ "${LAB:0:1}" = "/" ] && LAB='' || LAB="${LAB%%\"*}"
		UUID="${ONE_LINE#*UUID=\"}"
		[ "${UUID:0:1}" = "/" ] && UUID='' || UUID="${UUID%%\"*}"
		echo "$DRV" >> "$TMP_LIST"
		echo "$TYPE" >> "$TMP_LIST"
		echo "$LAB" >> "$TMP_LIST"
		echo "$UUID" >> "$TMP_LIST"
	done < "$TMP_BLK"

	if [ -s "$TMP_LIST" ]; then
		if [ "$SAVE_PART" ]; then
			TXT_INTRO="A separate save location is currently defined:
    <span foreground='purple'>${SAVE_PART}:${SAVE_DIR}</span>
To retain this definition, just click <span foreground='blue'>OK</span>.

"
		else
			TXT_INTRO="Defining a separate Linux default save partition is optional,
to continue without one, just click <span foreground='blue'>OK</span>.

"
		fi
		SAVE_SPEC="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Save partition" --width=270 --height=200 \
			--text "${TXT_INTRO}Current Puppies are capable of storing the savefolder separate from the install directory.
You might do this to install Puppy on an SSD but write the savefolder to a HD,
or to install Puppy on a non-Linux partition but use a savefolder on a Linux partition.

Select a Puppy save partition:" \
			--list --column=Part --column=Type --column=Label --column=UUID:HD < $TMP_LIST)"
		[ $? -eq 0 ] || error_exit
		rm "$TMP_LIST"
		if [ "$SAVE_SPEC" ]; then
			SAVE_PART="${SAVE_SPEC%%|*}"
			SAVE_SPEC="${SAVE_SPEC#*|}"; SAVE_SPEC="${SAVE_SPEC#*|}"
			SAVE_LABEL="${SAVE_SPEC%%|*}"
			SAVE_SPEC="${SAVE_SPEC#*|}"
			SAVE_UUID="${SAVE_SPEC%%|*}"
			if [ "$SAVE_LABEL" ]; then
				SAVE_ID="$SAVE_LABEL"
			else
				SAVE_ID="$SAVE_UUID"
			fi
			if [ "$SAVE_PART" ]; then
				ensure_mounted "$SAVE_PART"
				[ "$ensure_mounted_DID" ] && echo "$ensure_mounted_MP" >> "$MNTD_FN"
				[ "$ensure_mounted_MP" ] || error_exit "Could not mount \"$SAVE_PART\"."
				SAVE_MP="$ensure_mounted_MP"

				SAVE_DIR="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Save directory." \
					--file --directory --width=600 --height=400 \
					--text " Select the directory to contain the Puppy savefolder." \
					--filename="${SAVE_MP}${SAVE_DIR%/*}/")"
				[ $? -eq 0 ] || error_exit
				DIR_MP="$(stat -Lc %m "$SAVE_DIR")"
				if [ "$DIR_MP" != "$SAVE_MP" ]; then
					SAVE_PART="$(grep -m1 "$DIR_MP" /proc/mounts | cut -f1 -d' ')"
					SAvE_PART="${SAVE_PART#/dev/}"
					SAVE_MP="$DIR_MP"
				fi
				[ "$ensure_mounted_DID" ] && umount "$ensure_mounted_MP"
				SAVE_DIR="${SAVE_DIR#${SAVE_MP}}"
			fi
		fi
	fi
fi

#just in case
if [ "$SAVE_PART" = "$DEST_PART" ]; then
	if [ "$SAVE_DIR" = "$SFS_DIR" ]; then
		SAVE_PART=''
		SAVE_DIR=''
	fi
fi

XTRA_PARMS=''
if [ "$showKERNEL" ]; then
	DEF_PARMS="$frugalPARMS" 
	if [ "$DEF_PARMS" ]; then
		TMP_DIR="/tmp/${0##*/}_$$_tmp"
		[ -d "$TMP_DIR" ] && rm -rf "$TMP_DIR"
		mkdir -p "$TMP_DIR"
		[ -f "$TMP_LIST" ] && rm "$TMP_LIST"
		for ONE_PARM in $PKNLPARMS; do
			touch "$TMP_DIR/${ONE_PARM%=*}"
			echo 'TRUE' >> "$TMP_LIST"
			echo "$ONE_PARM" >> "$TMP_LIST"
		done
		for ONE_PARM in $DEF_PARMS; do
			[ -f "$TMP_DIR/${ONE_PARM%=*}" ] && continue
			echo 'FALSE' >> "$TMP_LIST"
			echo "$ONE_PARM" >> "$TMP_LIST"
		done
		[ -d "$TMP_DIR" ] && rm -rf "$TMP_DIR"
		PARM_SPEC="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Kernel boot parameters" --width=450  --height=330 \
		--text "There are many boot parameters defined for the Linux kernel.
The selection below is a very small sub-set of those.

The <span foreground='purple'>Settings</span> facility provides:
an option to change which kernel boot parmeters appear below,
and a reference to documentation of available kernel boot parameters.

If you are not sure, accept the default, and click the <span foreground='blue'>OK</span> button.
Otherwise, check the boxes of the desired kernel boot parameters.

Selected boot parameters are inserted into the  <span foreground='purple'>Grub2</span> boot-entry
generated by the <span foreground='purple'>Boot</span> and <span foreground='purple'>ISO</span> facilities." \
	--list --no-headers --checklist --print-column=2 --column=:CHK --column=:TXT < "$TMP_LIST")"
		[ $? -eq 0 ] || error_exit
		XTRA_PARMS="${PARM_SPEC%|}"
		XTRA_PARMS="${XTRA_PARMS//|
/ }"
	fi
else
	XTRA_PARMS="$PKNLPARMS"
fi

PFIX_PARMS=''
if [ "$showPFIX" ]; then
	NOX_VAL='FALSE'; NOCOPY_VAL='FALSE'; FSCK_VAL='FALSE'; FSCKP_VAL='FALSE'; TRIM_VAL='FALSE'
	if [ "$PFIXPARMS" ]; then
		IFS_BAK=$IFS; IFS=','
		for ONE_PARM in $PFIXPARMS; do
			case $ONE_PARM in
				nox) NOX_VAL='TRUE' ;;
				nocopy) NOCOPY_VAL='TRUE' ;;
				fsck) FSCK_VAL='TRUE' ;;
				fsckp) FSCKP_VAL='TRUE' ;;
				trim) TRIM_VAL='TRUE' ;;
			esac
		done
		IFS=$IFS_BAK
	fi
	VALS="$(yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - Pfix boot parameter" --form \
		--text="Manually override the <span foreground='purple'>pfix</span> boot parameter generated by the <span foreground='purple'>Boot</span> and <span foreground='purple'>BootCD</span> facilities.

A checked box indicates that the option will be included in the <span foreground='purple'>pfix</span> parameter." \
		--field="nox - do not start X:CHK" $NOX_VAL \
		--field="nocopy - don't copy sfs's to RAM:CHK" $NOCOPY_VAL \
		--field="fsck - fsck any savefile before mount:CHK" $FSCK_VAL \
		--field="fsckp - fsck ext partitions before fist mount:CHK" $FSCKP_VAL \
		--field="trim - add \"discard\" to mount command, if SSD:CHK" $TRIM_VAL )"
	[ $? -eq 0 ] || error_exit
	[ "$VALS" ] || error_exit "No values specified."
	[ "${VALS%%|*}" = "TRUE" ] && PFIX_PARMS="${PFIX_PARMS},nox"
	VALS="${VALS#*|}"
	[ "${VALS%%|*}" = "TRUE" ] && PFIX_PARMS="${PFIX_PARMS},nocopy"
	VALS="${VALS#*|}"
	[ "${VALS%%|*}" = "TRUE" ] && PFIX_PARMS="${PFIX_PARMS},fsck"
	VALS="${VALS#*|}"
	[ "${VALS%%|*}" = "TRUE" ] && PFIX_PARMS="${PFIX_PARMS},fsckp"
	VALS="${VALS#*|}"
	[ "${VALS%%|*}" = "TRUE" ] && PFIX_PARMS="${PFIX_PARMS},trim"
	PFIX_PARMS="${PFIX_PARMS#,}"
else
	PFIX_PARMS="$PFIXPARMS"
fi

SAVE_MSG=''
if [ "$SAVE_PART" ]; then
	if [ "$SAVE_DIR" ]; then
		SAVE_DIR_DISP="$SAVE_DIR"
	else
		SAVE_DIR_DISP='/'
	fi
	SAVE_MSG="

Default save location:
    Partition: <span foreground='purple'>$SAVE_PART</span> [<span foreground='purple'>$SAVE_ID</span>]
    Directory: <span foreground='purple'>$SAVE_DIR_DISP</span>"
fi

if [ "$XTRA_PARMS" ]; then
	DISP_PARMS="

Extra kernel parameters:
    <span foreground='purple'>$XTRA_PARMS</span>"
else
	DISP_PARMS=''
fi

if [ "$PFIX_PARMS" ]; then
	DISP_PFIX="

Pfix boot parameter:
    <span foreground='purple'>pfix=${PFIX_PARMS}</span>"
else
	DISP_PFIX=''
fi

DEST_DIR_DISP="$SFS_DIR"
[ "$DEST_DIR_DISP" ] || DEST_DIR_DISP='/'

if [ "$SRC_FN" ]; then
	SRC_DISP="$SRC_FN"
else
	SRC_DISP="$(realpath "$SRC_DIR")"
fi

yad $YAD_STD_OPTS --title "FrugalPup-puppyfiles v${VER} - confirm" --width=260 \
	--text "About to write Puppy frugal install files to:
    Partition: <span foreground='purple'>$DEST_PART</span> [<span foreground='purple'>$DEST_ID</span>]
    Directory: <span foreground='purple'>$DEST_DIR_DISP</span>

Puppy source:
    <span foreground='purple'>$SRC_DISP</span>${SAVE_MSG}${DISP_PARMS}${DISP_PFIX}

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

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

if [ "$SFS_DIR" ]; then
	EX_DEST="$DEST_PART:$SFS_DIR"
else
	EX_DEST="$DEST_PART"
fi
normal_exit "Puppy Linux written to <span foreground='purple'>$EX_DEST</span>."
