#!/bin/sh /etc/rc.common
# Copyright (C) 2012 Gui Iribarren
# Copyright (C) 2017 Daniel Golle
# This is free software, licensed under the GNU General Public License v3.

START=99
USE_PROCD=1
PROG=/usr/bin/watchping

append_string() {
	local varname="$1"; local add="$2"; local separator="${3:- }"; local actual
	eval "actual=\$$varname"

	new="${actual:+$actual$separator}$add"
	eval "$varname=\$new"
}

timetoseconds() {
	local time=$1
	unset seconds

	{ [ "$time" -ge 1 ] 2> /dev/null && seconds="$time"; } || \
	{ [ "${time%s}" -ge 1 ] 2> /dev/null && seconds="${time%s}"; } || \
	{ [ "${time%m}" -ge 1 ] 2> /dev/null && seconds=$((${time%m}*60)); } || \
	{ [ "${time%h}" -ge 1 ] 2> /dev/null && seconds=$((${time%h}*3600)); } || \
	{ [ "${time%d}" -ge 1 ] 2> /dev/null && seconds=$((${time%d}*86400)); }
}

load_watchping() {
	config_get interface	$1 interface
	config_get timeout	$1 timeout
	config_get pinghosts	$1 pinghosts	"8.8.8.8"
	config_get pinginterval	$1 pinginterval
	
	error=""

	ifname="$(uci_get_state network "$interface" ifname)"

	[ -z "$ifname" ] && {
		logger -p user.info -t "watchping" "interface $interface does not exist (yet?) waiting 10 seconds to try again"
		sleep 10
		ifname="$(uci_get_state network "$interface" ifname)"
		[ -z "$ifname" ] && {
			logger -p user.info -t "watchping" "interface $interface does not exist in openwrt but continuing..."
			ifname="$interface"
		}
	}

	timetoseconds "$timeout"
	timeout="$seconds"
	[ "$timeout" -ge 1 ] \
		|| append_string "error" 'timeout is not a valid time value (ex: "30"; "4m"; "6h"; "2d")' "; "
	[ -n "$pinghosts" ] \
		|| append_string "error" "pinghosts must be set" "; "
	if [ -n "$pinginterval" ] ;	then
		timetoseconds "$pinginterval"
		pinginterval="$seconds"
		if [ "$pinginterval" -ge 0 ] ; then
			[ "$pinginterval" -le "$timeout" ] \
				|| append_string "error" "pinginterval must be less than timeout" "; "
		else
			append_string "error" 'pinginterval is not a valid time value (ex: "30"; "4m"; "6h"; "2d")' "; "
		fi
	else
		pinginterval="$((timeout/20))"
	fi
	
	[ "$pinginterval" -le "$timeout" ] \
		|| append_string "error" "pinginterval is not recognised" "; "

	[ -n "$error" ] && { logger -p user.err -t "watchping" "daemon $1 not started - $error"; return; }

	procd_open_instance
	procd_set_param command $PROG "$ifname" "$timeout" "$pinghosts" "$pinginterval" "$interface"
	procd_set_param stderr 1
	procd_close_instance

	logger -p user.info -t "watchping" "started task (interface=$ifname;timeout=$timeout;pinghosts=$pinghosts;pinginterval=$pinginterval;hookname=$interface)"
}

start_service() {
	config_load system
	if [ -n "$(uci show system.@watchping[0])" ] # at least one watchping section exists
	then
		logger -p user.info -t "watchping" "starting all tasks"
		config_foreach load_watchping watchping
		logger -p user.info -t "watchping" "all tasks started"
	else
		logger -p user.info -t "watchping" "no tasks defined"
	fi
}

watch_interfaces() {
	local cfg="$1"
	local ping_interface
	config_get ping_interface "$cfg" "interface"
	trigger_interfaces="${ping_interface} ${trigger_interfaces} "
}

service_triggers() {
	local trigger_interfaces
	config_load system
	config_foreach watch_interfaces watchping

	procd_add_reload_trigger "watchping"
	if [ "$trigger_interfaces" ]; then
		for iface in $trigger_interfaces; do
			logger -p user.info -t "watchping" "adding ifup trigger for $iface"
			procd_add_interface_trigger "interface.*.up" "$iface" /etc/init.d/watchping restart
			procd_add_interface_trigger "interface.*.update" "$iface" /etc/init.d/watchping restart
		done
	fi
}
