#!/bin/bash

version="3.0"

function ferrexit() {
    [ "$1" != "" ] && printf "$1"
    [ "$plugfile" != "" ] && rm -f $plugfile
    docleanup
    exit 1
}

function doctrlc() {
    printf "% Final cleanup. Please wait...\n"
    ferrexit ""
}

function doexit() {
    ferrexit "Exit\n"
}

function waitdev() { 
    while [ 1 ]
    do
	[ -b $burndev ] && return
	echo -n "% Ready device '$burndev' and press Enter: " read ans
    done
}   

function plugwrite() {
    # $1: string to write
    echo "$1" >> $plugfile
}

function writeuser() {
    # user: username, password WRT makeuser, sudo
    local plugstring="" usudo=""
    [ "$sudo" == "no" ] && usudo="|nosudo"
    if [ "$makeuser" == "yes" ]
    then
	plugstring="adduser=$username|password=${password}${usudo}"
    fi
    [ "$plugstring" != "" ] && plugwrite "user:$plugstring"
}

function writel10n() {
    # L10n: keymap, locale, timezone,
    local l10nstring=""
    [ "$keymap" != "" ] && l10nstring="keymap=$keymap"
    [ "$locale" != "" ] && { [ "$l10nstring" == "" ] && l10nstring="locale=$locale" || l10nstring="${l10nstring}|locale=$locale" ; }
    [ "$timezone" != "" ] && { [ "$l10nstring" == "" ] && l10nstring="timezone=$timezone" || l10nstring="${l10nstring}|timezone=$timezone" ; }
    [ "$l10nstring" != "" ] && plugwrite "l10n:$l10nstring"
}

function writenetwork() {
    # network: wifissid, wifipassword, wificountry
    local netstring=""
    [ "$wifissid" != "" ] && netstring="wifissid=$wifissid"
    [ "$wifipassword" != "" ] && { [ "$netstring" == "" ] && netstring="wifipassword=$wifipassword" || netstring=${netstring}|wifipassword=$wifipassword" ; }
    [ "$wificountry" != "" ] && { [ "$netstring" == "" ] && netstring="wificountry=$wificountry" || netstring=${netstring}|wificountry=$wificountry" ; }
    [ "$nmconn" != "" ] &&  { [ "$netstring" == "" ] && netstring="nmconn=$nmconn" || netstring="${netstring}|nmconn=$nmconn" ; }
    [ "$netstring" != "" ] && plugwrite "network:$netstring"
}

function writelxde() {
    # lxde: mouse=left
    if [ "$mouse" == "left" ]
    then
	plugwrite "lxde:lhmouse=yes"
    fi
}

function writepiwiz() {
    # disables: piwiz
    if [ "$piwiz" == "no" ]
    then
	plugwrite "disables:piwiz"
    fi
}

#
# Main code
#
# Read lines from input file
#    Each line is complete for one user. Supported options (all on a single line in the input file, separated by commas,  no spaces)
#    username password=userpwd,wifissid=wifissidforuser,wifipassword=wifipasswordforuser,hostname=userhostname,
#            wificountry=wc,keymap=km,locale=lc,timezone=tz,sudo=no,makeuser=no,
#            nmconn=file,file,pluglist=/path/to/pluglist,
#            piwiz=yes,autologin=yes,reboot=20,mouse=left,keepi=yes
#
#    Defaults:
#            hostname: $username
#            makeuser: yes
#            sudo: yes
#            wificountry: US
#            k/m/t: Get from host? or leave as is
#            piwiz: no
#            autologin: no
#            reboot: 0 (no auto-reboot)
#            mouse: right
#
# $1:  IMG
# $2:  input data file (per above)
# $3:  Burn device (/dev/sdX)

src=$(dirname "$(realpath "$0")")
source $src/sdm-cparse
trap "doexit" EXIT
img=$1
[ "$img" == "" ] && errexit "Usage: $0 IMGname datafile burndev"
[ ! -f "$img" ] && errexit "? IMG file '$img' not found"
df=$2
[ "$df" == "" ] && errexit "? Data file required"
burndev=$3
[ "$burndev" == "" ] && errexit "? Burn device required"
perr=0
for p in 1 2 3 4
do
    pdev="${burndev}${p}"
    ismounted $pdev && echo "? Partition $pdev is mounted" && perr=1
done
[ $perr -eq 1 ] && errexit "? Use 'sudo umount' to dismount each listed partition, then rerun $0"
ismounted $burndev && errexit "? Device '$burndev' is mounted"
#
# Check that IMG has been sdm-enhanced
#
echo "* Validate IMG '$img' is sdm-enhanced"
declare -x SDMPT=$(makemtpt)
set -m  # Enable job control
trap "doctrlc" SIGINT
domount "$img" "IMG"
#echo "> IMG '$img' mounted on $SDMPT"
[ -d $SDMPT/etc/sdm ] && fenh=1 || fenh=0
#doumount
docleanup
trap SIGINT
[ $fenh -eq 1 ] && echo "* IMG '$img' is sdm-enhanced" || errexit "? IMG '$img' is not sdm-enhanced"
plugfile=/tmp/gburn.plugins
#
# Use readarray rather than reading a line at a time. Line at a time changes stdin
# and breaks prompting inside the loop
#
printf "\n* Begin processing data file '$df'\n"
readarray -t lines < $df
for line in "${lines[@]}"
do
    #
    # Comment lines start with a '#' in column 1
    #
    if ! [[ "$line" =~ ^#.* ]] && ! [[ "$line" == "" ]]
    then
	rm -f $plugfile
	username=${line%% *}  # Line starts with "username "
	args=${line#* }      # Get rest of args (everything after the space)
	password=""
	wifissid=""
	wifipassword=""
	wificountry=""
	keymap=""
	locale=""
	timezone=""
	makeuser="yes"
	keepi="no"
	sudo="yes"
	piwiz="no"
	autologin="no"
	reboot="20"
	mouse="right"
	nmconn=""
	pluglist=""
	hostname=""
	echo "* Configuration for '$username'"
	IFS="," read -a citems <<< "$args"
	for c in "${citems[@]}"
	do
            IFS=":=" read key value <<< "$c"
	    key=$(stripquotes "$key")
	    value="$(stripquotes "$value")"
            echo ">  $key=$value"
	    eval "${key}=\"$value\""
	done

	[ "$makeuser" != "yes" ] && sudo="no" && autologin="no" #Disable adding sudo if not creating user

	if [ "$wificountry" == "" ]
	then
	    #echo "% No 'wificountry=' configured; Using US"
	    wificountry="US"  # Prepend this default when we copy into the IMG
	fi
	#
	# Write plugin list file
	#
	writeuser
	writel10n
	writenetwork
	writelxde
	writepiwiz

	if [[ "$username" != "" && "$password" != "" ]] || [[ "$makeuser" == "no" ]]
	then
	    [ "$hostname" == "" ] && hostname="$username"
	    while [ 1 ]
	    do
		echo -n "Ready to burn '$burndev' for '$username'? [YES/no/skip/quit/list/help] " ;  read ans
		[ "$ans" == "" ] && ans="y" || ans="${ans,,}"
		ans1="${ans:0:1}"
		sfdisk -l $burndev > /dev/null 2>&1
		sts=$?
		if [[ "qnsy" =~ "$ans1" ]]
		then
		    [[ $sts -eq 0 ]] && break
		    [[ "qns" =~ "$ans1" ]] && break
		fi
		if [ "$ans1" == "l" ]
		then
		    echo "** Plugin list for '$username':"
		    cat $plugfile
		else
		    if [ "$ans1" == "h" ]
		    then
			echo "Valid [case-insensitive] responses:"
			echo " Y - Burn the disk for '$username' (or press ENTER)"
			echo " N or S - Skip burning disk for '$username'"
			echo " Q - Do not burn the disk for '$username' and exit"
			echo " L - Display the generated plugins for '$username'"
			echo " H - Print this help"
		    else
			e=1
			[[ ! "qnsyl" =~ "$ans1" ]] && e=0 && echo "% Unrecognized response '$ans'; Responses are: Yes/no/skip/quit/list"
			[[ $e -eq 1 ]] && echo "% Insert disk '$burndev'"
		    fi
		fi
	    done
	    case "$ans1" in
		n|s)
		    echo "% Skipping '$username'"
		    docleanup
		    ;;
		q)
		    echo "% Quit"
		    docleanup
		    exit 0
		    ;;
		y|*)
		    [ "$reboot" != "0" ] && rb="--reboot $reboot" || rb=""
		    [ "$autologin" == "yes" ] && al="--autologin" || al=""
		    trap "doctrlc" SIGINT
		    [ "$keepi" != "yes" ] && pins="--plugin user:deluser=pi"
		    [ -f $plugfile ] && pins="$pins --plugin @$plugfile"
		    [ "$pluglist" != "" ] && pins="$pins --plugin @pluglist"
		    echo "sdm --burn $burndev --hostname $hostname --expand-root  --regen-ssh-host-keys $rb $al $pins $img"
		    sdm --burn $burndev --hostname $hostname --expand-root --regen-ssh-host-keys $rb $al $pins $img
		    trap SIGINT
		    docleanup
		    echo "* Disk for '$username' completed"
		    ;;
	    esac
	else
	    if [ "$username" != "" -a "$password" == "" -a "$makeuser" == "yes" ]
	    then
		echo "% Skipping user '$username'; password required"
	    fi
	fi
    fi
done
exit 0
