#!/bin/bash
#
# PS: The caller of this script can make changes to SIP.config after calling this
# script. The caller should not initiate the script in background as it might have
# un-intended consequence of backing up the new config if the change happen before the
# script gets scheduled!!!

tools_path=/usr/local/bin
app_state="/run/sip.state"
app_config="/etc/nyquist/SIP.config"
interface_config="/etc/network/interfaces"
ppid=$1
vlan_id=$2

create_config_backup()
{
	if [ ! -f ${app_config}.bak ]; then
		# Preserve timestamps on copy, to be useful later
		cp -p ${app_config} ${app_config}.bak
	fi
	return 1
}

delete_config_backup()
{
	if [ -f ${app_config}.bak ]; then
		unlink ${app_config}.bak
		return 1
	fi
	return 0
}

rollback_config()
{
	if [ -f ${app_config}.bak ]; then
		mv ${app_config}.bak ${app_config}
		${tools_path}/restart_application no_update 2>&1 | logger -p user.info -t "$0[$$]"
		systemd-run --no-block --service-type=idle ${tools_path}/network_set rollback default "$vlan_id"
		return 1
	fi
	return 0
}

load_variables()
{
	while read cmd_line; do
		[ -n "$cmd_line" ] && declare -g $cmd_line
	done <<- END
		`sed -e "/\(^#\|^$\)/d" -e "s/\s*//g" ${app_state}`
	END
}

monitor_rollback()
{
	sec_sleep=5
	sec_threshold=120

	config_mtime=`stat -c %Y ${app_config}`
	config_bak_mtime=`stat -c %Y ${app_config}.bak`
	load_variables
	
	# loop forever!!! until a new config arrives and app starts using it
	retry=1
	while [ $retry -eq 1 ]; do
		# Do we have a new config
		if [ $config_mtime == $config_bak_mtime ]; then
			logger -p user.info -t "$0[$$]" "Waiting for new config (file time) ${config_mtime} == ${config_bak_mtime}"
			sleep ${sec_sleep}
			config_mtime=`stat -c %Y ${app_config}`
		else
			config_md5sum=(`md5sum ${app_config}`)
			load_variables
			if [ "${config_md5sum}" == "${CONFIG_CSUM}" ]; then
				retry=0
			else
				logger -p user.info -t "$0[$$]" "Waiting for app config (md5sum) ${config_md5sum} != ${CONFIG_CSUM}"
				sleep ${sec_sleep}
			fi
		fi
	done

	retry=0
	retry_count=$((${sec_threshold} / ${sec_sleep}))
	while [ ${REGISTRATION_FAILURE} -ne 0 -a ${retry} -le ${retry_count} ]; do
		retry=$((${retry} + 1))
		load_variables
		sleep ${sec_sleep}
	done

	if [ ${REGISTRATION_FAILURE} -ne 0 ]; then
		logger -p user.info -t "$0[$$]" "Registration failure using config $CONFIG_CSUM"
		rollback_config
	else
		logger -p user.info -t "$0[$$]" "Registration success using config $CONFIG_CSUM"
		# Now that the config was good check if there is a firmware update
		systemd-run --no-block --service-type=idle  ${tools_path}/check_for_updates server
	fi
}

# Make sure we don't run multiple times and the first to execute survives
cmd_string=(${0//// })
cmd=${cmd_string[${#cmd_string[*]} - 1]}

tmp_ifs="$IFS"
IFS=$'\n'

ps_list=(`ps -C ${cmd} -o pid --no-header`)
num_copies=${#ps_list[*]}
if [ $num_copies -gt 1 -a ${ps_list[0]:-0} -ne ${ppid:-$$} ]; then
	logger -p user.warning -t "$0[$$]" "Running $num_copies copies viz ${ps_list[*]}"
	exit 0
fi

IFS="$tmp_ifs"

#if [ ! -f ${app_state} ]; then
#	logger -p user.warning "$0[$$] Client is not running to identify a rollback condition"
#	delete_config_backup
#	exit 1;
#fi

create_config_backup
if [ "${1:-$$}" -eq $$ ]; then
	# Rollback monitoring is being initiated, spawn a background instance
	vlan_iface=`sed -n -e "s/^\s*auto\s*\(eth0\.[:digit:]*\)/\1/p" $interface_config`
	systemd-run --no-block --service-type=idle $0 "$$" "${vlan_iface/eth0\./}" &
	disown -a 2>&1 | logger -t "$0[$$]"
else
	monitor_rollback
	delete_config_backup
fi

exit 0
