#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
# Copyright (c) Khadas
#
# Tool to transfer the rootfs of an already running Armbian installation from SD card
# to eMMC or USB storage. In case of eMMC it's also possible to transfer
# the bootloader to eMMC in a single step so from then on running without SD card is
# possible.

# Import:
# DIR: path to u-boot directory
# write_uboot_platform: function to write u-boot to a block device

[[ -f /usr/lib/u-boot/platform_install.sh ]] && source /usr/lib/u-boot/platform_install.sh

# script configuration
CWD="/usr/lib/emmc-install"
EX_LIST="${CWD}/exclude.txt"
[ -f /etc/default/openmediavault ] && echo '/srv/*' >> "${EX_LIST}"
logfile="/var/log/emmc-install.log"

# read in board info
[[ -f /etc/fenix-release ]] && source /etc/fenix-release
backtitle="Fenix for Khadas $BOARD install script."
title=" eMMC, USB and NVMe Fenix installer v${VERSION}"

# check release version
# only support V0.7 and newer version
if linux-version compare $VERSION lt 0.7; then
	dialog --title "$title" --backtitle "$backtitle" --colors --infobox '\n\Z1This tool only support Fenix V0.7 and newer version! \Zn' 5 56
	exit -1
fi

case ${VENDOR} in
	Rockchip)
		FIRSTSECTOR=32768
		UBOOT_PACKAGE_UPDATE=no
		;;
	*)
		FIRSTSECTOR=8192
		UBOOT_PACKAGE_UPDATE=no
		;;
esac

#recognize_root
root_uuid=$(sed -e 's/^.*root=//' -e 's/ .*$//' < /proc/cmdline)
root_partition=$(blkid | tr -d '":' | grep "${root_uuid}" | awk '{print $1}')
root_partition_device="${root_partition::-2}"

# find targets: EMMC, SPI flash, NVMe
emmccheck=$(ls -d -1 /dev/mmcblk* | grep -w 'mmcblk[0-9]' | grep -v "$root_partition_device");
diskcheck=$(lsblk -l | awk -F" " '/ disk / {print $1}' | grep -E '^sd|^nvme')
spicheck=$(grep 'mtd' /proc/partitions | awk '{print $NF}')

# boot filesystem & root filesystem
ROOTFS_TYPE="ext4"
BOOTFS_TYPE="fat"

if ! grep -qE '/boot.*fat' /etc/fstab; then
	# we use ext4 on newer devices
	BOOTFS_TYPE="ext4"
fi

# define makefs and mount options
declare -A parttype mkopts mountopts mkfs mounttype

parttype[fat]=fat32
parttype[ext4]=ext4

mkopts[fat]=''
mkopts[ext4]='-q -F -m 2 -O ^64bit,^metadata_csum'

mkfs[fat]=vfat
mkfs[ext4]=ext4

mounttype[fat]=vfat
mounttype[ext4]=ext4

mountopts[fat]='defaults 0 2'
mountopts[ext4]='defaults,noatime,nodiratime,commit=600,errors=remount-ro,x-gvfs-hide	0	1'

# Create boot and root file system "$1" = boot, "$2" = root (Example: create_filesystem "/dev/mmcblk0p1" "/dev/mmcblk0p2")
create_filesystem()
{
	# create mount points, mount and clean
	TempDir=$(mktemp -d /mnt/${0##*/}.XXXXXX || exit 2)
	sync &&	mkdir -p "${TempDir}"/bootfs "${TempDir}"/rootfs
	[[ -n $2 ]] && ( mount "$2" "${TempDir}"/rootfs 2> /dev/null || mount "$2" "${TempDir}"/rootfs )
	[[ -n $1 && $1 != "spi" ]] && mount "$1" "${TempDir}"/bootfs
	rm -rf "${TempDir}"/bootfs/* "${TempDir}"/rootfs/*

	# root part
	# UUID=xxx...
	rootfsuuid=$(blkid -o export "$2" | grep -w UUID)

	# UUID=xxx...
	bootfsuuid=$emmcbootuuid

	# write information to log
	echo -e "\nOld UUID:  ${root_uuid}" >> $logfile
	echo "ROOTFS UUID: $rootfsuuid" >> $logfile
	echo "BOOTFS UUID: $bootfsuuid" >> $logfile
	echo "eMMC UUID: $emmcrootuuid" >> $logfile
	echo "Boot: \$1 $1 $BOOTFS_TYPE" >> $logfile
	echo "Root: \$2 $2 $ROOTFS_TYPE" >> $logfile

	# calculate usage and see if it fits on destination
	USAGE=$(df -BM | grep ^/dev | head -1 | awk '{print $3}' | tr -cd '[0-9]. \n')
	DEST=$(df -BM | grep ^/dev | grep "${TempDir}"/rootfs | awk '{print $4}' | tr -cd '[0-9]. \n')
	if [[ $USAGE -gt $DEST ]]; then
		dialog --title "$title" --backtitle "$backtitle" --colors --infobox\
		"\n\Z1Partition too small.\Zn Needed: $USAGE MB Avaliable: $DEST MB" 5 60
		umount_device "$1"; umount_device "$2"
		exit 3
	fi

	# write information to log
	echo "Usage: $USAGE" >> $logfile
	echo -e "Dest: $DEST\n\n/etc/fstab:" >> $logfile
	cat /etc/fstab >> $logfile
	echo -e "\n/etc/mtab:" >> $logfile
	grep '^/dev/' /etc/mtab | grep -E -v "log2ram|folder2ram" | sort >> $logfile

	# stop running services
	echo -e "\nFiles currently open for writing:" >> $logfile
	lsof / | awk 'NR==1 || $4~/[0-9][uw]/' | grep -v "^COMMAND" >> $logfile
	echo -e "\nTrying to stop running services to minimize open files:\c" >> $logfile
	stop_running_services "nfs-|smbd|nmbd|winbind|ftpd|netatalk|monit|cron|webmin|rrdcached" >> $logfile
	stop_running_services "fail2ban|ramlog|folder2ram|postgres|mariadb|mysql|postfix|mail|nginx|apache|snmpd" >> $logfile
	pkill dhclient 2>/dev/null
	LANG=C echo -e "\n\nChecking again for open files:" >> $logfile
	lsof / | awk 'NR==1 || $4~/[0-9][uw]/' | grep -v "^COMMAND" >> $logfile

	# count files is needed for progress bar
	dialog --title " $title " --backtitle "$backtitle" --infobox "\n  Counting files ... few seconds." 5 60
	TODO=$(rsync -ahvrltDn --delete --stats --exclude-from=$EX_LIST / "${TempDir}"/rootfs | grep "Number of files:"|awk '{print $4}' | tr -d '.,')
	echo -e "\nCopying ${TODO} files to $2. \c" >> $logfile

	# creating rootfs
	# Speed copy increased x10
	 # Variables for interfacing with rsync progress
	nsi_conn_path="${TempDir}/emmc-install"
	nsi_conn_done="${nsi_conn_path}/done"
	nsi_conn_progress="${nsi_conn_path}/progress"
	mkdir -p "${nsi_conn_path}"
	echo 0 >"${nsi_conn_progress}"
	echo no >"${nsi_conn_done}"

	 # Launch rsync in background
	{ \
	rsync -avrltD --delete --exclude-from=$EX_LIST / "${TempDir}"/rootfs | \
	nl | awk '{ printf "%.0f\n", 100*$1/"'"$TODO"'" }' \
	> "${nsi_conn_progress}" ;
	 # save exit code from rsync
	echo  ${PIPESTATUS[0]} >"${nsi_conn_done}"
	} &

	 # while variables
	rsync_copy_finish=0
	rsync_progress=0
	prev_progress=0
	rsync_done=""
	while [ "${rsync_copy_finish}" -eq 0 ]; do
		# Sometimes reads the progress file while writing and only partial numbers (like 1 when is 15)
		prev_progress=${rsync_progress}
		rsync_progress=$(tail -n1 "${nsi_conn_progress}")
		if [[ -z ${rsync_progress} ]]; then
			rsync_progress=${prev_progress}
		fi
		if [ ${prev_progress} -gt ${rsync_progress} ]; then
			rsync_progress=${prev_progress}
		fi
		echo "${rsync_progress}"
		# finish the while if the rsync is finished
		rsync_done=$(cat ${nsi_conn_done})
		if [[ "${rsync_done}" != "no" ]]; then
			if [[ ${rsync_done} -eq 0 ]]; then
				rm -rf "${nsi_conn_path}"
				rsync_copy_finish=1
			else
				# if rsync return error
				echo "Error: could not copy rootfs files, exiting"
				exit 4
			fi
		else
			sleep 0.5
		fi

	done | \
	dialog --backtitle "$backtitle" --title " $title " --gauge "\n\n  Transferring rootfs to $2 ($USAGE MB). \n\n \
	 This will take approximately $(( $((USAGE/300)) * 1 )) minutes to finish. Please wait!\n\n" 11 80

	# run rsync again to silently catch outstanding changes between / and "${TempDir}"/rootfs/
	dialog --title "$title" --backtitle "$backtitle" --infobox "\n  Cleaning up ... Almost done." 5 40
	rsync -avrltD --delete --exclude-from=$EX_LIST / "${TempDir}"/rootfs >/dev/null 2>&1

	# creating fstab from scratch
	rm -f "${TempDir}"/rootfs/etc/fstab
	mkdir -p "${TempDir}"/rootfs/etc

	# Restore TMP and swap
	echo "# <file system>					<mount point>	<type>	<options>							<dump>	<pass>" > "${TempDir}"/rootfs/etc/fstab
	echo "tmpfs						/tmp		tmpfs	defaults,nosuid							0	0" >> "${TempDir}"/rootfs/etc/fstab
	grep swap /etc/fstab >> "${TempDir}"/rootfs/etc/fstab

	# Boot from eMMC, root = eMMC or USB
	#
	if [[ $2 == ${emmccheck}p* || $1 == ${emmccheck}p* ]]; then

		if [[ $2 == ${DISK_ROOT_PART} ]]; then
			echo "Finalizing: boot from eMMC, rootfs on USB/NVMe." >> $logfile
		else
			echo "Finishing full install to eMMC." >> $logfile
		fi

		REMOVESDTXT="and remove SD to boot from eMMC/USB/NVMe"

		# fix that we can have one exlude file
		cp -aR /boot/. "${TempDir}"/bootfs
		# new boot scripts
		if [[ -f "${TempDir}"/bootfs/env.txt ]]; then
			sed -e 's,rootdev=.*,rootdev='"$rootfsuuid"',g' -i "${TempDir}"/bootfs/env.txt
			grep -q '^rootdev' "${TempDir}"/bootfs/env.txt || echo "rootdev=$rootfsuuid" >> "${TempDir}"/bootfs/env.txt
			# if the rootfstype is not defined as cmdline argument on env.txt
			# Add the line of type of the selected rootfstype to the file env.txt
			grep -qE '^rootfstype=.*' "${TempDir}"/bootfs/env.txt || echo "rootfstype=$ROOTFS_TYPE" >> "${TempDir}"/bootfs/env.txt
			sed -e 's,rootfstype=.*,rootfstype='$ROOTFS_TYPE',g' -i "${TempDir}"/bootfs/env.txt
		fi

		if [[ -f "${TempDir}"/bootfs/uEnv.txt ]]; then
			sed -e 's,rootdev=root=.*,rootdev=root='"$rootfsuuid"',g' -i "${TempDir}"/bootfs/uEnv.txt
			grep -q '^rootdev' "${TempDir}"/bootfs/uEnv.txt || echo "rootdev=root=$rootfsuuid" >> "${TempDir}"/bootfs/uEnv.txt
			sed -e 's,partitiontype=partition_type=.*,partitiontype=partition_type=generic,g' -i "${TempDir}"/bootfs/uEnv.txt
			# Add the line of type of the selected rootfstype to the file uEnv.txt, if not already defined
			grep -qE '^rootfstype=.*' "${TempDir}"/bootfs/uEnv.txt || echo "rootfstype=$ROOTFS_TYPE" >> "${TempDir}"/bootfs/uEnv.txt
			sed -e 's,rootfstype=.*,rootfstype='$ROOTFS_TYPE',g' -i "${TempDir}"/bootfs/uEnv.txt
		fi

		# fstab adjust
		if [[ "$1" != "$2" ]]; then
			echo "$bootfsuuid   				/boot		${mounttype[$BOOTFS_TYPE]}	${mountopts[$BOOTFS_TYPE]}" >> "${TempDir}"/rootfs/etc/fstab
		fi

		echo "$rootfsuuid	/		${mounttype[$ROOTFS_TYPE]}	${mountopts[$ROOTFS_TYPE]}" >> "${TempDir}"/rootfs/etc/fstab

		# update installation type
		if [[ $2 != ${DISK_ROOT_PART} ]]; then
			sed -i "s/INSTALL_TYPE=.*/INSTALL_TYPE=EMMC_MBR/" "${TempDir}"/rootfs/etc/fenix-release
		fi

		if [[ $(type -t write_uboot_platform) != function ]]; then
			echo "Error: no u-boot package found, exiting"
			exit 6
		fi
		write_uboot_platform "$DIR" $emmccheck
	fi

	# Boot from SPI, root = USB
	#
	if [[ $1 == *spi* ]]; then
		if [[ -f "${TempDir}"/bootfs/env.txt ]]; then
			sed -e 's,rootdev=.*,rootdev='"$rootfsuuid"',g' -i "${TempDir}"/rootfs/boot/env.txt
		fi
		if [[ -f "${TempDir}"/bootfs/uEnv.txt ]]; then
			sed -e 's,rootdev=root=.*,rootdev=root='"$rootfsuuid"',g' -i "${TempDir}"/rootfs/boot/uEnv.txt
		fi
		echo "$rootfsuuid	/		${mounttype[$ROOTFS_TYPE]}	${mountopts[$ROOTFS_TYPE]}" >> "${TempDir}"/rootfs/etc/fstab
	fi

	# recreate OMV mounts at destination if needed
	grep -q ' /srv/' /etc/fstab
	if [ $? -eq 0 -a -f /etc/default/openmediavault ]; then
		echo -e '# >>> [openmediavault]' >> "${TempDir}"/rootfs/etc/fstab
		grep ' /srv/' /etc/fstab | while read ; do
			echo "${REPLY}" >> "${TempDir}"/rootfs/etc/fstab
			mkdir -p -m700 "${TempDir}/rootfs$(awk -F" " '{print $2}' <<<"${REPLY}")"
		done
		echo -e '# <<< [openmediavault]' >> "${TempDir}"/rootfs/etc/fstab
	fi

	echo -e "\nChecking again for open files:" >> $logfile
	lsof / | awk 'NR==1 || $4~/[0-9][uw]/' | grep -v "^COMMAND" >> $logfile
	LANG=C echo -e "\n$(date): Finished\n\n" >> $logfile
	cat $logfile > "${TempDir}"/rootfs${logfile}
	sync

	umount "${TempDir}"/rootfs
	[[ $1 != "spi" ]] && umount "${TempDir}"/bootfs
} # create_filesystem

# Accept device as parameter: for example /dev/sda unmounts all their mounts
umount_device()
{
	if [[ -n $1 ]]; then
		device="$1";
		for n in ${device}*; do
			if [[ $device != "$n" ]]; then
				if mount|grep -q "$n"; then
					umount -l "$n" >/dev/null 2>&1
				fi
			fi
		done
	fi
} # umount_device

# formatting eMMC [device] example /dev/mmcblk1 - one can select filesystem type
#
format_emmc()
{
	# create fs
	# deletes all partitions on eMMC drive
	dd bs=1 seek=446 count=64 if=/dev/zero of="$1" >/dev/null 2>&1
	# calculate capacity and reserve some unused space to ease cloning of the installation
	# to other media 'of the same size' (one sector less and cloning will fail)
	QUOTED_DEVICE=$(echo "$1" | sed 's:/:\\\/:g')
	CAPACITY=$(parted "$1" unit s print -sm | awk -F":" "/^${QUOTED_DEVICE}/ {printf (\"%0d\", \$2 / ( 1024 / \$4 ))}")

	if [[ $CAPACITY -lt 4000000 ]]; then
		# Leave 2 percent unpartitioned when eMMC size is less than 4GB (unlikely)
		LASTSECTOR=$(( 32 * $(parted "$1" unit s print -sm | awk -F":" "/^${QUOTED_DEVICE}/ {printf (\"%0d\", ( \$2 * 98 / 3200))}") -1 ))
	else
		# Leave 1 percent unpartitioned
		LASTSECTOR=$(( 32 * $(parted "$1" unit s print -sm | awk -F":" "/^${QUOTED_DEVICE}/ {printf (\"%0d\", ( \$2 * 99 / 3200))}") -1 ))
	fi

	parted -s "$1" -- mklabel msdos
	parted -s "$1" -- mkpart primary ${parttype[$BOOTFS_TYPE]} ${FIRSTSECTOR}s 524287s
	parted -s "$1" -- mkpart primary ${parttype[$ROOTFS_TYPE]} 524288s ${LASTSECTOR}s
	parted -s "$1" set 1 boot on
	partprobe "$1"
	dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating $1"p1" to $BOOTFS_TYPE ... please wait." 5 60
	eval "mkfs.${mkfs[$BOOTFS_TYPE]} ${mkopts[$BOOTFS_TYPE]} ${1}p1" >> $logfile 2>&1
	dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating $1"p2" to $ROOTFS_TYPE ... please wait." 5 60
	eval "mkfs.${mkfs[$ROOTFS_TYPE]} ${mkopts[$ROOTFS_TYPE]} ${1}p2" >> $logfile 2>&1
	emmcrootuuid=$(blkid -o export "$1"'p2' | grep -w UUID)
	emmcbootuuid=$(blkid -o export "$1"'p1' | grep -w UUID)
}


# formatting USB/NVMe partition, examples: /dev/sda3 or /dev/nvme0n1p1
#
format_disk()
{
	# create fs
	dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating $1 to $ROOTFS_TYPE ... please wait." 5 60
	mkfs.${mkfs[$ROOTFS_TYPE]} ${mkopts[$ROOTFS_TYPE]} "$1" >> $logfile 2>&1
}


# choose target USB/NVMe partition.
check_partitions()
{
	IFS=" "
	AvailablePartitions=$(lsblk -l | awk -F" " '/ part | raid..? / {print $1}' | grep -E '^sd|^nvme|^md')
	if [[ -z $AvailablePartitions ]]; then
		dialog --title "$title" --backtitle "$backtitle" --colors --msgbox \
		"\n\Z1There are no avaliable partitions. Please create them.\Zn" 7 60
		# We need gdisk for proper partition alignment
		apt-get -y -q install gdisk >/dev/null 2>&1
		gdisk /dev/$diskcheck
	fi
	AvailablePartitions=$(lsblk -l | awk -F" " '/ part | raid..? / {print $1}' | grep -E '^sd|^nvme|^md' | uniq | sed 's|^|/dev/|' | nl | xargs echo -n)
	PartitionOptions=($AvailablePartitions)

	PartitionCmd=(dialog --title 'Select destination:' --backtitle "$backtitle" --menu "\n$infos" 10 60 16)
	PartitionChoices=$("${PartitionCmd[@]}" "${PartitionOptions[@]}" 2>&1 >/dev/tty)

	[[ $? -ne 0 ]] && exit 11
	DISK_ROOT_PART=${PartitionOptions[(2*$PartitionChoices)-1]}
}

# build and update new bootscript
update_bootscript()
{
	echo "TODO"
}

# show warning [TEXT]
show_warning()
{
	dialog --title "$title" --backtitle "$backtitle" --cr-wrap --colors --yesno " \Z1$(toilet -W -f ascii9 WARNING)\Zn\n$1" 14 54
	[[ $? -ne 0 ]] && exit 13
}

# try to stop running services
stop_running_services()
{
	systemctl --state=running | awk -F" " '/.service/ {print $1}' | sort -r | \
		grep -E -e "$1" | while read ; do
		echo -e "\nStopping ${REPLY} \c"
		systemctl stop ${REPLY} 2>&1
	done
}

main()
{
	export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

	# This tool must run under root
	if [[ $EUID -ne 0 ]]; then
		echo 'This tool must run as root. Exiting ...' >&2
		exit 14
	fi

	# Check if we run it from SD card
	# TODO: Disable/remove this in the future
	case ${root_partition_device} in
		/dev/mmcblk*) # mmc device, we can continue
			:
			;;
		*)
			dialog --title "$title" --backtitle "$backtitle" --colors --infobox '\n\Z1This tool must run from SD-card! \Zn' 5 42
			exit 15
			;;
	esac

	[ -f $logfile ] && echo -e '\n\n\n' >> $logfile
	LANG=C echo -e "$(date): Start ${0##*/}.\n" >> $logfile

	if [[ ${UBOOT_PACKAGE_UPDATE} = yes ]]; then
		IFS="'"
		options=()
		options+=(1 "Vendor u-boot")
		[[ ${BOARD} = VIM1 || ${BOARD} = VIM2 || ${BOARD} = VIM3 || ${BOARD} = VIM3L ]] && options+=(2 "Mainline u-boot")
		cmd=(dialog --title 'Choose the U-boot' --backtitle "$backtitle" --menu "\n Choose the U-boot you want to use \n \n" 14 40 7)
		choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
		[[ $? -ne 0 ]] && exit 16

		for choice in $choices
		do
			case $choice in
				1)
					uboottype="vendor"
					;;
				2)
					uboottype="mainline"
					;;
			esac
		done

		installed_uboot_package=`dpkg -l | grep linux-u-boot | awk '{print $2}'`
		installed_uboot_package_type=`echo $installed_uboot_package | awk -F '-' '{print $5}'`
		uboot_package="linux-u-boot-${BOARD,,}-${uboottype}"
		if [[ ${uboot_package} = ${installed_uboot_package} ]]; then
			# already installed
			UBOOT_PACKAGE_UPDATE=no
		fi

		echo "installed_uboot_package: $installed_uboot_package" >> $logfile
		echo "uboot_package: $uboot_package" >> $logfile
		echo "UBOOT_PACKAGE_UPDATE: $UBOOT_PACKAGE_UPDATE" >> $logfile

		if [[ ${UBOOT_PACKAGE_UPDATE} = yes ]]; then
			# update u-boot package
			dialog --title "Update u-boot package" --backtitle "$backtitle" --colors --yesno \
			"\n Install u-boot package from fenix repo?\n" 7 60
			[[ $? -ne 0 ]] && exit 13
			apt-get -q update
			apt-get -q install -y --reinstall $uboot_package
			[[ $? -ne 0 ]] && exit 13
		else
			dialog --title "$title" --backtitle "$backtitle" --cr-wrap --colors --yesno "\n U-boot package already updated! Continue? \n" 6 50
			[[ $? -ne 0 ]] && exit 13
		fi
	fi

	IFS="'"
	options=()
	if [[ -n $emmccheck ]]; then
		ichip='eMMC';
		dest_boot=$emmccheck'p1'
		dest_root=$emmccheck'p2'
	fi

	# Boot + RootFS relocation options
	[[ -n $emmccheck ]] && options+=(1 "Boot from $ichip - system on $ichip (fully install to eMMC)")
	[[ -n $emmccheck  && -n $diskcheck ]] && options+=(2 "Boot from $ichip - system on USB or NVMe (install to USB/NVMe)")
	[[ -n $spicheck ]] && options+=(3 'Boot from SPI  - system on USB or NVMe (install to USB/NVMe)')

	# U-boot install/update options
	[[ -n ${root_partition_device} ]] && options+=(4 'Install/Update the bootloader on SD/eMMC')
	[[ -n $spicheck && $(type -t write_uboot_platform_mtd) == function ]] && options+=(5 'Install/Update the bootloader on SPI Flash')

	[[ ${#options[@]} -eq 0 || "$root_uuid" == "$emmcrootuuid" ]] && \
	dialog --ok-label 'Cancel' --title ' Warning ' --backtitle "$backtitle" --colors --no-collapse --msgbox '\n\Z1There are no targets. Please check your drives.\Zn' 7 52
	cmd=(dialog --title 'Choose an option:' --backtitle "$backtitle" --menu "\nCurrent root: $root_uuid \n \n" 14 70 7)
	choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
	[[ $? -ne 0 ]] && exit 16

	for choice in $choices
	do
		case $choice in
			1)
				title="$ichip install"
				command='Power off'
				show_warning "This script will erase your $ichip. Continue?"
				if [[ -n $emmccheck ]]; then
					umount_device "$emmccheck"
					format_emmc "$emmccheck"
				fi
				create_filesystem "$dest_boot" "$dest_root"
				;;
			2)
				title="$ichip boot | USB/NVMe root install"
				command='Power off'
				check_partitions
				show_warning "This script will erase your $ichip and $DISK_ROOT_PART. Continue?"
				if [[ -n $emmccheck ]]; then
					umount_device "$emmccheck"
					format_emmc "$emmccheck"
				fi
				umount_device "${DISK_ROOT_PART//[0-9]*/}"
				format_disk "$DISK_ROOT_PART"
				create_filesystem "$dest_boot" "$DISK_ROOT_PART"
				;;
			3)
				# TODO
				# Espressobin has flash boot by default
				title='SPI flash boot | USB/NVMe root install'
				command='Power off'
				# we need to copy boot
				sed -i '/boot/d' $EX_LIST
				check_partitions
				show_warning "This script will erase your device $DISK_ROOT_PART. Continue?"
				format_disk "$DISK_ROOT_PART"
				create_filesystem 'spi' "$DISK_ROOT_PART"
				;;
			4)
				show_warning 'This script will update the bootloader on SD/eMMC. Continue?'
				write_uboot_platform "$DIR" "${root_partition_device}"
				update_bootscript
				dialog --backtitle "$backtitle" --title 'Writing bootloader' --msgbox '\n          Done.' 7 30
				return
				;;
			5)
				MTD_BLK="/dev/${spicheck}"
				show_warning "This script will update the bootloader on SPI Flash $MTD_BLK. Continue?"
				write_uboot_platform_mtd "$DIR" $MTD_BLK
				update_bootscript
				echo 'Done'
				return
				;;
		esac
	done

	dialog --title "$title" --backtitle "$backtitle" --yes-label "$command" --no-label 'Exit' --yesno "\nAll done. $command $REMOVESDTXT" 7 70
	[[ $? -eq 0 ]] && "$(echo ${command,,} | sed 's/ //')"
} # main

main "$@"
