#!/bin/sh /etc/rc.common

START=10
USE_PROCD=1

. /lib/functions.sh

MODEDIR="/etc/netmodes"
SUPP_MODES_SEC=""

_log() {
	logger -s -p user.info -t "netmode" "$*"
}

libnetmode_exec() {
	when="$1"
	# Execute /lib/netmode scripts
	if [ -d /lib/netmode/$when ]; then
		_log "Executing /lib/netmode/$when scripts"
		for script in $(ls /lib/netmode/$when/); do
			sh /lib/netmode/$when/$script
		done
	fi
}

_get_modes_sec_name() {
	local sec mode name

	sec="${1}"
	mode="${2}"

	config_get name ${1} name ""
	if [ "${name}" = "${mode}" ]; then
		SUPP_MODES_SEC="${sec}"
		break;
	fi
}

_set_env_args() {
	local sec name value required dm_parent

	sec="${1}"

	config_get_bool required ${sec} required "0"
	config_get name ${sec} name ""
	config_get value ${sec} value ""
	config_get dm_parent ${sec} dm_parent ""

	if [ -z "${dm_parent}" ]; then
		continue;
	fi

	if [ "${dm_parent}" != "${SUPP_MODES_SEC}" ]; then
		continue;
	fi

	if [ "${required}" -eq "1" ]; then
		if [ -z "${name}" -o -z "${value}" ]; then
			_log "Can't apply mode, name[${name}] or value[${value}] is missing"
			exit 0
		fi
	fi

	if [ -n "${name}" -a -n "${value}" ]; then
		export NETMODE_${name}="${value}"
	fi
}

configure_env_vars() {
	local mode

	mode="${1}"
	if [ -z "${mode}" ]; then
		_log "mode info missing"
		exit 0
	fi

	SUPP_MODES_SEC=""
	config_load "netmode"
	config_foreach _get_modes_sec_name supported_modes "${mode}"

	if [ -z "${SUPP_MODES_SEC}" ]; then
		_log "mode ${mode} not found in uci"
		exit 0
	fi

	config_foreach _set_env_args supported_args
}

cleanup_arg_values() {
	local dm_parent

	config_get dm_parent ${1} dm_parent ""
	if [ "${dm_parent}" = "${SUPP_MODES_SEC}" ]; then
		uci -q set netmode.${1}.value=""
	fi
}

cleanup_env_vars() {
	for e in $(env); do
		if echo ${e} |grep -q "^NETMODE_"; then
			unset ${e}
		fi
	done

	if [ -n "${SUPP_MODES_SEC}" ]; then
		config_load "netmode"
		config_foreach cleanup_arg_values supported_args
		uci commit netmode
	fi
}

start_service() {
	[ -f /etc/config/netmode ] || return

	config_load netmode
	config_get_bool enabled global enabled '0'
	[ $enabled -eq 0 ] && return

	# Get the desired netmode from config
	config_get mode global mode ""
	# Check if netmode is set as boot environment parameter
	[ -n "$mode" ] || mode="$(fw_printenv -n netmode 2>/dev/null)"
	# Return if mode is not set
	[ -n "$mode" ] || return

	# Get the last saved mode
	lastmode="$(cat $MODEDIR/.last_mode 2>/dev/null)"
	# Return if desired mode is same as last saved mode
	[ "$mode" == "$lastmode" ] && return

	_log "Switching to [${mode}] Mode" >/dev/console

	# Configure env variables
	configure_env_vars ${mode}
	# Execute netmode generic pre-mode-switch scripts
	libnetmode_exec "pre"

	# Copy netmode UCI config files
	if [ -d $MODEDIR/$mode/uci ]; then
		_log "Copying $MODEDIR/$mode/uci/* to /etc/config/"
		cp $MODEDIR/$mode/uci/* /etc/config/ 2>/dev/null
	fi

	# Execute netmode generic scripts
	libnetmode_exec

	# Execute mode specific scripts
	if [ -d $MODEDIR/$mode/scripts ]; then
		_log "Executing $MODEDIR/$mode/scripts/* scripts"
		for script in $(ls $MODEDIR/$mode/scripts/); do
			sh $MODEDIR/$mode/scripts/$script
		done
	fi

	# Execute netmode generic post-mode-switch scripts
	libnetmode_exec "post"
	cleanup_env_vars "${mode}"

	# Save mode as last mode
	[ -d $MODEDIR ] || mkdir -p $MODEDIR
	echo "$mode" > $MODEDIR/.last_mode
	_log "Switching to Mode [${mode}] done, last mode updated" >/dev/console
}

service_triggers()
{
	procd_add_reload_trigger netmode
}
