#!/usr/bin/env bash

set -e
set -u
#et -x

function usage
{
	echo "$0: Create bootable USB key from UBCD a la Reblu"
	echo
	echo "Usage:    $0 --ubcd-location UBCD-path --usb-key-mount-point USB-path --usb-device USB-device [-v]"
	echo
	echo "Example:  $0 --ubcd-location /path/to/ubcd/extracted --usb-key-mount-point /usb/key/path --usb-device /dev/sda1"
	echo '          (UBCD-CDROM at '/path/to/ubcd/extracted', USB-key to be temporarily mounted at /usb/key/path)'
	echo
	echo 'Required: Linux or Unix'
}

ubcd_location=""
usb_key_location=""
usb_device=""
verbosity=0

while [ "$#" -ge 1 ]
do
	if [ "$1" = --ubcd-location ]
	then
		ubcd_location="$2"
		shift
	elif [ "$1" = --usb-key-mount-point ]
	then
		usb_key_location="$2"
		shift
	elif [ "$1" = --usb-device ]
	then
		usb_device="$2"
		shift
	elif [ "$1" = -v ]
	then
		verbosity=$[$verbosity+1]
	elif [ "$1" = -h ] || [ "$1" = --help ]
	then
		usage 0
	else
		usage 1
	fi
	shift
done

if [ "$ubcd_location" = "" ]
then
	echo --ubcd-location is required 1>&2
	usage 1
fi

if [ "$usb_key_location" = "" ]
then
	echo --usb-key-mount-point is required 1>&2
	usage 1
fi

if [ "$usb_device" = "" ]
then
	echo --usb-device is required 1>&2
	usage 1
fi

case "$usb_device" in
	*[0-9])
		echo Sorry, the USB device you specify must be the whole device, not a partition. 1>&2
		echo A partition will be created though. 1>&2
		exit 1
		;;
esac

function quiet_run
{
	if ! output=$(eval "$@" 1>&2)
	then
		(
		echo "command $@ failed"
		echo "$output"
		) 1>&2
		exit 1
	fi
}

function must_exist
{
	file="$1"
	if [ -f "$file" ]
	then
		return 0
	else
		echo File "$file" does not exist, and this script "($0)" needs it to 1>&2
		exit 1
	fi
}

if [ "$verbosity" -ge 1 ]
then
	echo $0: Creating bootable USB drive from UBCD 1>&2
fi

for fn in ldlinux.bss ldlinux.sys mbr.bin makebootfat
do
	must_exist "$fn"
done

if [ "$verbosity" -ge 1 ]
then
	echo $0: Launching 'makebootfat' to format USB drive 1>&2
fi
./makebootfat \
	$([ "$verbosity" -ge 2 ] && echo -v) \
	-D \
	-o "$usb_device" \
	-Y \
	-Z \
	-b ldlinux.bss \
	-m mbr.bin \
	-c ldlinux.sys \
	ubcdroot

quiet_run mount "$usb_device"4 "$usb_key_location"

for fn in "$ubcd_location"/ubcd/ubcd.css "$usb_key_location"/ldlinux.sys
do
	must_exist "$fn"
done

if [ "$verbosity" -ge 1 ]
then
	echo "$0: Transfering UBCD-base ($ubcd_location) to USB drive ($usb_key_location)"
fi
#quiet_run [ -f excl_dir.lst ]
case 2 in
	1)
		(cd "$ubcd_location" && tar -c -S -f - --one-file-system .) | \
			if [ "$verbosity" -ge 2 ]
			then
				reblock $[2**20] 300
			else
				cat
			fi | \
			(cd "$usb_key_location" && tar xfp -)
		;;
	2)
		tempfile="$(mktemp -p /tmp -t $(basename $0).XXXXXX)"
		if [ "$verbosity" -ge 1 ]
		then
			trap "rm $tempfile" $(seq 0 15)
			(cd "$ubcd_location" && tar -c -S -f - --one-file-system .) > "$tempfile"
			reblock < "$tempfile" $[2**20] 300 | \
				(cd "$usb_key_location" && tar xfp -)
		else
			(cd "$ubcd_location" && tar -c -S -f - --one-file-system .) | \
				(cd "$usb_key_location" && tar xfp -)
		fi
		;;
esac

quiet_run rm "$usb_key_location"/{boot.catalog,autorun.inf,ubcd.ico}

if [ "$verbosity" -ge 1 ]
then
	echo $0: Moving UBCD images 1>&2
fi
case "2" in
	0)
		(cd "$ubcd_location"/images && tar cflS - .) | (cd "$usb_key_location" && tar xfp -)
		;;
	1)
		# worked, Sun Feb 18 11:02:12 PST 2007
		cd "$usb_key_location"
		cp images/* .
		;;
	2)
		# worked, Sun Feb 18 11:02:25 PST 2007
		#cd "$usb_key_location"
		mv "$usb_key_location"/images/* "$usb_key_location"/.
		rmdir "$usb_key_location"/images
		;;
	3)
		# this mess was a binary search, due to a test iteration that produced bizarre results
		cd "$usb_key_location"
#		count=$(find . -type d -print | \
#			egrep -v '^\./images$' | \
#			wc -l)
		# 0-100 worked
		# 0-50 worked
		# 0-25 worked
		# 0-12.5 worked
		#	percent --start 0 --end 6 | \ worked
#			percent --start 0 --end 3 | \ worked
#			percent --start 0 --end 1.5 | \ worked
#			percent --start 0 --end 0.75 | \ worked
#			percent --start 0 --end 0.3 | \ worked
		find . -type d -print | \
			egrep -v '^\./images$' | \
			percent --start 0 --end 0.15 | \
			while read dir
			do
				echo Copying to "$dir"...
				cp ./images/cpuburn.igz "$dir"/.
			done
		;;
esac

#echo $0: Checking for "$usb_key_location"/freedos.img
if [ -f "$usb_key_location"/fdubcd.img ] && [ -f "$usb_key_location"/freedos.img ]
then
	quiet_run rm "$usb_key_location"/freedos.img
	quiet_run cp "$usb_key_location"/fdubcd.img "$usb_key_location"/freedos.img
fi

quiet_run cd / # actually, if this fails, we've got larger problems :)
quiet_run umount "$usb_key_location"

if [ "$verbosity" -ge 1 ]
then
	echo "$0": Bootable USB version of UBCD ready 1>&2
fi