#!/bin/bash
#
# This script runs at first boot to perform desired configuration
#

function doscripts() {
    #
    # $1: wildcard file spec
    # $2: Scripts name
    #
    local fns="$1" sname="$2"
    for f in $fns
    do
	[ ! -e "$f" ] && continue        #Skip if file doesn't exist; probably no files in dir so get $fns back
	if [ -x $f ]
	then
	    bootlog "Run $sname Script '$f'"
	    bash $f
	else
	    bootlog "$sname Script '$f' does not have execute permission"
	fi
    done
}    

function doconfig() {
    cfgfile="$1"
    [ ! -f $cfgfile ] && bootlog "? Config file $cfgfile not found...skipping" && exit
    #write_console "Start Configuration with configuration file '$cfgfile'"
    bootlog "Start Configuration with configuration file '$cfgfile'"
    while IFS=":=" read rpifun value
    do
	if [[ ! $rpifun =~ ^\ *# && -n $rpifun ]] # skip comment and malformed lines
	then
	    value="${value%%\#*}"    # Del EOL comments
	    value=$(stripquotes "$value")
	    doconfigitem $rpifun $value bootlog
	fi
    done < $cfgfile
    #write_console "Configuration with configuration file '$cfgfile' Completed"
    bootlog "Configuration with configuration file '$cfgfile' Completed"
}

function waitreport() {
    svc=$1
    if [ $((secs%10)) -eq 0 ]
    then
        logger "$servicename: $svc service not yet started"
    fi
}

function waitcheck() {
    local sts
    if [ "$(systemctl show -p UnitFileState systemd-timesyncd --value)" == "enabled" ]
    then
        if [[ "$(systemctl show -p ActiveState  systemd-timesyncd --value)" == "active" ]]
        then
            [ "$(timedatectl status | grep synchronized | (IFS=' ' ; read a b c d ; echo $d))" == "yes" ] && return 0 || return 1
        else
            waitreport systemd-timesyncd
            return 1
        fi
    elif [ "$(systemctl show -p UnitFileState chrony --value)" == "enabled" ]
    then
        if [[ "$(systemctl show -p ActiveState  chrony --value)" == "active" ]]
        then
            sts="$(chronyc tracking | grep Reference)"
            #logger "FirstBoot: chronyc tracking: $sts"
            [[ "$sts" =~ "00000000" ]] || [[ "$sts" == "" ]] && return 1
            return 0
        else
            waitreport chrony
            return 1
        fi
    else
        if [ $((secs%10)) -eq 0 ]
        then
            logger "$servicename: Unable to identify time sync service; Neither systemd-timesyncd or chronyd are active"
        fi
        return 1
    fi
}

function timesyncwait() {
    #
    # Waits for time to be synced or 120 seconds
    #
    # Skip if --nowait-timesync
    #
    if [ $nowaittimesync -eq 1 ]
    then
	write_console "Skip wait for time synchronization per --nowait-timesync"
	bootlog "Skip wait for time synchronization per --nowait-timesync"
	return
    fi

    swait=120
    for (( secs=1 ; secs<=$swait ; secs++ ))
    do
	waitcheck && break
	if [ $secs -eq $swait ]
	then
	    write_console "System time not synchronized after $swait second wait; Proceeding..."
	    bootlog "System time not synchronized after $swait second wait; proceeding to regenerate SSH host keys"
	    return
	fi
	if [ $((secs%10)) -eq 0 ]
	then
	    write_console "Waiting $secs/$swait seconds for system time synchronization"
	    bootlog "Waiting $secs/$swait seconds for system time synchronization"
	fi
	sleep 1
    done
    bootlog "System time synchronization achieved"
    write_console "System time synchronization achieved"
    return
}

function wait_startup_complete {
    # $1 is the message to write
    local lc=0 msg=$1
    # Can't use this test VV because boot_behaviour might change it, so need to check both graphical.target and multi-user.target
    # while [ "$(systemctl show -p ActiveState $(systemctl get-default) --value)" != "active" ]
    while [ "$(systemctl show -p ActiveState graphical.target --value)" != "active" -a "$(systemctl show -p ActiveState multi-user.target --value)" != "active" ]
    do
	if [ $lc -eq 0 ]
	then
	   bootlog "$msg"
	   write_console "$msg"
	   lc=1
	fi
	sleep 1
    done
}

#
# Mainline
#
if [ "$1" == "" ]
then
    $0 "fork" &         # Fork and restart myself so forking service is started
    exit
fi
#
# Now running in the fork
#
declare -x SDMNSPAWN="FirstBoot"
source /etc/sdm/sdm-readparams

write_console "Start sdm FirstBoot Service"
bootlog "Start sdm FirstBoot Service"

#
# Run any scripts that are must run ASAP (like network configuration)
#
if [ -d /etc/sdm/xpiboot ]
then
    if compgen -G "/etc/sdm/xpiboot/*" > /dev/null
    then
	chmod 755  /etc/sdm/xpiboot/0*-*.sh  #Ensure all executable
	doscripts "/etc/sdm/xpiboot/0*-*.sh" "Generated sdm FirstBoot"
    fi
fi

[ -f /etc/sdm/auto-1piboot.conf ] && doconfig /etc/sdm/auto-1piboot.conf

[ "$wificountry" == "" ] && wificountry="US"
bootlog "Set WiFi Country to '$wificountry'"
do_raspiconfig do_wifi_country "$wificountry"

[ -f /etc/sdm/local-1piboot.conf ] && bootlog "Run Localization Settings from Captive Portal in /etc/sdm/local-1piboot.conf" && doconfig /etc/sdm/local-1piboot.conf
#
# Wait for network online
#
timesyncwait
#
#  run scripts internally generated by sdm
#
if compgen -G "/etc/sdm/0piboot/*" > /dev/null
then
   chmod 755 /etc/sdm/0piboot/0*-*.sh   #Ensure all executable
   doscripts "/etc/sdm/0piboot/0*-*.sh" "Generated sdm FirstBoot"
fi

#
# Only look at 1piboot.conf if there's anything to process
#
[ -f /etc/sdm/1piboot.conf ] && [ "$(grep -v -e '#' /etc/sdm/1piboot.conf | grep -v -e '^$' | wc -l)" != "0" ] && doconfig /etc/sdm/1piboot.conf

#
# Final FirstBoot time processing: custom scripts and reboot
#
[ "$bootscripts" == "1" ] && doscripts "$sdmdir/1piboot/0*-*.sh" "Custom sdm FirstBoot" || bootlog "Skip Custom sdm FirstBoot Scripts"

logit "> sdm FirstBoot: Disable sdm-firstboot service"
systemctl disable sdm-firstboot > /dev/null 2>&1

if [ $regensshkeys -eq 1 ]
then
    write_console "Regenerate SSH Host Keys"
    bootlog "Regenerate SSH Host Keys"
    systemctl start regenerate_ssh_host_keys
    while [ "$(systemctl show -p ActiveState regenerate_ssh_host_keys --value)" == "active" ]
    do
	sleep 1
    done
fi
rm -f /etc/ssh/sshd_not_to_be_run

if [ $reboot -eq 1 -a $noreboot -ne 1 ]
then
    wait_startup_complete "System will restart automatically after system startup has completed"
    [ -f /etc/sdm/assets/cryptbbh ] && bootlog "Skip set boot behavior per cryptroot plugin" || do_delayed_boot_behavior reboot
    write_console "System startup complete; System will restart in $rebootwait seconds"
    bootlog "System will restart in $rebootwait seconds"
    sleep $rebootwait
    systemctl daemon-reload
    write_console "System restarting now\n"
    bootlog "System restarting now"
    systemctl reboot
else
    [ "$(systemctl is-enabled ssh)" == "enabled" -a $reboot -ne 1 ] && systemctl start ssh
    wait_startup_complete "System will continue without restarting after system startup has completed"
    [ -f /etc/sdm/assets/cryptbbh ]  && bootlog "Skip set boot behavior per cryptroot plugin" || do_delayed_boot_behavior noreboot
    write_console "System startup complete"
    bootlog "System startup complete"
fi
exit 0

