#!/bin/sh

PIDFILE=/var/run/monitor.pid
if [ -e ${PIDFILE} ] && kill -0 `cat ${PIDFILE}` 2>/dev/null ; then
	echo "already running"
	exit
fi
echo $$ > ${PIDFILE}
trap "rm -f ${PIDFILE}; exit" INT TERM EXIT

[ -z "$ROOT" ] && ROOT=/www
CONFIG=$ROOT/config
SCRIPT=$ROOT/script

[ -s "$CONFIG/ng.conf" ] && source $CONFIG/ng.conf
source $CONFIG/ap.conf
source $CONFIG/api.conf

source $SCRIPT/utils/date.sh
source $SCRIPT/utils/wifi.sh
source $SCRIPT/utils/network.sh
source $SCRIPT/utils/token.sh
source $SCRIPT/utils/misc.sh

log="logger -t monitor"

goOnline() {
	ssids=`getEnabledSsidList`
	radios=`getRadioCount`
	for ssid in $ssids ; do
		for radio in `seq 1 $radios` ; do
			"$SCRIPT/setup/setup-wireless-ssid.sh" "$ssid" "$radio"
		done
	done
}

enableDebug() {
	uci set wireless.debug.disabled=0
}

disableDebug() {
	uci set wireless.debug.disabled=1
}

monitorWanInf() {
	# Sometime wan inf is not created
	local wanInf=`getWanInf`
	ifconfig $wanInf &>/dev/null
	if [ $? -ne 0 ] ; then
		$log -p warn "interface $wanInf is not available, restarting network"
		/etc/init.d/network reload
	fi
}

monitorIptables() {
	# Prevent no rule or double rules
	local ruleCount=`iptables -t nat -vnL PREROUTING | grep HOTSPOT | wc -l`
	if [ "$ruleCount" -ne 1 ] ; then
		$log -p warn "iptables may in incorrect state, reloading ng_ap"
		/etc/init.d/ng_ap2 restart
	fi
}

monitorBishbosh() {
	# Restart job if needed
	local now=`date +%Y%m%d%H%M%S`
	local last30SecsInMin=$(((now - 30) / 100)) # to min
	touch /tmp/now.job-ref -d "$last30SecsInMin"
	local isJobStillRun=`find /tmp -name now.job -newer /tmp/now.job-ref`
	if [ -z "$isJobStillRun" ] ; then
		statsData="`json=true $SCRIPT/report/stats.sh`"
    sessionData="`json=true $SCRIPT/report/session.sh`"

		wget -T 5 -qO /dev/null $(getAuthHeader) \
			--header 'Content-Type: application/json' \
			--post-data="{\"stats\": $statsData, \"sessions\": $sessionData}" \
				"$CLOUD_ADDRESS/status"

		/etc/init.d/ng_ap2 restart job
	fi
}

monitorStationDump() {
	# station dump
	local stationDump=`ps | grep collector/station.sh | grep -v grep`
	[ -z "$stationDump" ] && sh /www/script/collector/station.sh 2>/dev/null >/dev/null &
}

monitorTcpdump() {
	[ "`which tcpdump`" ] || return
	# ua dump
	uaDump=`ps | grep "tcpdump" | grep "tcp dst port 80"`
	[ -z "$uaDump" ] && sh /www/script/collector/ua.sh

	# dhcp dump
	dhcpDump=`ps | grep "tcpdump" | grep "port 67 or port 68"`
	[ -z "$dhcpDump" ] && sh /www/script/collector/dhcp.sh 2>/dev/null >/dev/null &
}

monitorUhttpd() {
	# Restart uhttpd if needed
	local isUhttpdEnabled="`uci show uhttpd.hotspot.listen_http 2>/dev/null`"
	[ -z "$isUhttpdEnabled" ] && return

	local isUhttpdAlive="`pgrep uhttpd`"
	[ -z "$isUhttpdAlive" ] && /etc/init.d/uhttpd restart
}

monitorNetwork() {
	# Ignore network monitor on 3G devices
	if [ ! -z "$MOBILE_DEV" ] ; then
		echo online
		return
	fi

	# Monitor using ping
	[ -z "$WAN_MONITOR_NETWORK_IP1" ] && WAN_MONITOR_NETWORK_IP1="$CLOUD"
	[ -z "$WAN_MONITOR_NETWORK_IP2" ] && WAN_MONITOR_NETWORK_IP2="$DNS1"
	[ -z "$WAN_MONITOR_NETWORK_IP3" ] && WAN_MONITOR_NETWORK_IP3="$DNS2"

	local ping1=`pingAddress "$WAN_MONITOR_NETWORK_IP1"`
	local ping2=`pingAddress "$WAN_MONITOR_NETWORK_IP2"`
	local ping3=`pingAddress "$WAN_MONITOR_NETWORK_IP3"`
	local pingCount=$((ping1 + ping2 + ping3))

	if [ "$pingCount" == 0 ] ; then
		echo offline
	else
		echo online
	fi
}

monitorStatus() {
	local status=`monitorNetwork`
	local schedule="`$SCRIPT/setup/setup-schedule.sh`"

	local debugDisable=`uci get wireless.debug.disabled`
	[ "$debugDisable" == 1 ] && lastStatus=online || lastStatus=offline

	local now=`date +%Y%m%d%H%M%S`

	local curHash=`md5 /etc/config/wireless`
	if [ "$status" == offline ] ; then
		goOffline
		enableDebug
		if [ -f /tmp/offline ] ; then
		 	local offlineAt="`cat /tmp/offline`"
		else
			local offlineAt="$now"
			echo -n $offlineAt > /tmp/offline
		fi
		local offlineDiff="$((now - offlineAt))"
		$log -p warn "network offline for ${offlineDiff}s"
	else
		[ "$schedule" == online ] && goOnline && $log -p info "network online"
		disableDebug
		rm -rf /tmp/offline /etc/offline
	fi
	uci commit
	local newHash=`md5 /etc/config/wireless`

	[ "$curHash" != "$newHash" ] && wifi
	if [ "$lastStatus" != "$status" ] && [ "$status" == online ] ; then
		/etc/init.d/ng_ap2 restart time
	fi
	if [ "$status" == offline ] ; then
		if [ "$offlineDiff" -gt 600 ] && [ ! -f /etc/offline ] ; then
			touch /etc/offline /etc/banner && reboot
		elif [ "$offlineDiff" -gt 120 ] ; then
			sh $SCRIPT/monitor-config.sh
		fi
	fi
}

monitor() {
	monitorWanInf
	monitorIptables
	monitorBishbosh
	monitorStationDump
	monitorTcpdump
	monitorUhttpd
	monitorStatus
}

while true ; do
	sleep 5
	[ -f /tmp/booted ] || continue
	[ -f /tmp/applying ] && continue
	[ -f /tmp/installing ] && continue
	monitor
	sleep 10
done
