#!/bin/sh
# Copyright (C) 2015 PIVA Software <www.pivasoftware.com>
# 	Author: MOHAMED Kallel <mohamed.kallel@pivasoftware.com>
# 	Author: AHMED Sahnoun <ahmed.sahnoun@pivasoftware.com>


[ "$1" != "run" -a "$1" != "stop" ] && return

UCI_GET_VARSTATE="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state get"
UCI_SET_VARSTATE="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state set"
DEFAULTIMEMIN=9999999
DEFAULTIMEMIND=9999999999

ipping_get() {
	local val=`$UCI_GET_VARSTATE $1`
	echo ${val:-$2}
}


ipping_run() {
	[ "`$UCI_GET_VARSTATE easycwmp.@local[0].DiagnosticsState`" = "Requested" ] && ipping_initiation
	[ "`$UCI_GET_VARSTATE easycwmp.@local[0].ServerSelectionDiagnosticsState`" = "Requested" ] && ipping_Selection_initiation
}

ipping_Selection_initiation() {
	local i res ba stc times sc1 success_count failure_count min_time avg_time max_time avg_time_sum min max State
	local Selection_avg_time Selection_max_time Selection_min_time FastestHost host
	[ "`$UCI_GET_VARSTATE easycwmp.@local[0].ServerSelectionProtocol`" != "ICMP" ] && return
	local hostList=`ipping_get easycwmp.@local[0].SelectionDiagnosticsHostList`
	[ "$hostList" = "" ] && return
	local cnt=`ipping_get easycwmp.@local[0].ServerSelectionNumberOfRepetitions 1`
	local dsize=24
	local timeout=`ipping_get easycwmp.@local[0].ServerSelectionTimeout 1000`
	local Interface=`ipping_get easycwmp.@local[0].ServerSelectionInterface`
	local ProtocolVersion=`ipping_get easycwmp.@local[0].ServerSelectionProtocolVersion`
	
	ind=1;
	while [ $ind != "0" ]; do
		ind=$(expr index "$hostList" ",")
		host=${hostList:0:$ind}
		hostList=${hostList:$ind}
		[ "$ind" = "0" ] && host=$hostList
		host=${host//,/}
		ipping_launch
		[ -n "$State" ] && { $UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionDiagnosticsState=$State; event_dignostic; return; }
		[ "$min_time" = "$DEFAULTIMEMIN" ] && continue
		[ "$Selection_avg_time" -gt "$avg_time" ]  ||  [ -z "$FastestHost" ] && {
			FastestHost=$host
			Selection_avg_time=$avg_time
			Selection_min_time=$min_time
			Selection_max_time=$max_time
		}
	done

	[ -z "$FastestHost" ] && { $UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionDiagnosticsState=Error_CannotResolveHostName; event_dignostic; return; }
	$UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionDiagnosticsState=Complete
	$UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionFastestHost=$FastestHost
	$UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionAverageResponseTime=$Selection_avg_time
	$UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionMinimumResponseTime=$Selection_min_time
	$UCI_SET_VARSTATE easycwmp.@local[0].ServerSelectionMaximumResponseTime=$Selection_max_time
	event_dignostic
}

ipping_initiation() {
	local i res ba stc times sc1 success_count failure_count min_time avg_time max_time avg_time_sum min max State
	local avg_time_d min_time_d max_time_d
	local host=`ipping_get easycwmp.@local[0].Host`
	local cnt=`ipping_get easycwmp.@local[0].NumberOfRepetitions 3`
	local dsize=`ipping_get easycwmp.@local[0].DataBlockSize 64`
	local timeout=`ipping_get easycwmp.@local[0].Timeout 1000`
	local Interface=`ipping_get easycwmp.@local[0].Interface`
	local ProtocolVersion=`ipping_get easycwmp.@local[0].ProtocolVersion`
	[ "$host" = "" ] && return
	ipping_launch
	[ -n "$State" ] && { $UCI_SET_VARSTATE easycwmp.@local[0].DiagnosticsState=$State; event_dignostic; return; }

	$UCI_SET_VARSTATE easycwmp.@local[0].DiagnosticsState=Complete
	$UCI_SET_VARSTATE easycwmp.@local[0].SuccessCount=$success_count
	$UCI_SET_VARSTATE easycwmp.@local[0].FailureCount=$failure_count
	$UCI_SET_VARSTATE easycwmp.@local[0].AverageResponseTime=$avg_time
	$UCI_SET_VARSTATE easycwmp.@local[0].MinimumResponseTime=$min_time
	$UCI_SET_VARSTATE easycwmp.@local[0].MaximumResponseTime=$max_time

	$UCI_SET_VARSTATE easycwmp.@local[0].AverageResponseTimed=$avg_time_d
	$UCI_SET_VARSTATE easycwmp.@local[0].MinimumResponseTimed=$min_time_d
	$UCI_SET_VARSTATE easycwmp.@local[0].MaximumResponseTimed=$max_time_d


	event_dignostic
}

ipping_launch() {
	[ "$host" = "" ] && return
	timeout=$((timeout/1000))
	[ "$timeout" = "0" ] && timeout="1"
	success_count=0
	avg_time_sum=0
	avg_time_sum_d=0
	min=$DEFAULTIMEMIN
	min_d=$DEFAULTIMEMIND
	max=0
	max_d=0
	i=0
	if [ "$ProtocolVersion" = "IPv6" ]
	then
		ProtocolVersion="ping6"
	else
		ProtocolVersion="ping"
	fi
	[ "$Interface" != "" ] && { 
		ubusInterface=`echo {\"interface\":\"$Interface\"}`
		iface=`ubus call "network.interface" "status" $ubusInterface`
	}
	[ "$iface" != "" ] && {
		json_init
		json_load "$iface" >&2
		json_get_var device device >&2
		if [ "$device" != "" ] 
			then
				Device=`echo -I $device`
			else
				Device=""
			fi
		}
	
	while [ $i -lt $cnt ]; do
		let i++
		res=$($ProtocolVersion -q -c 1 $Device -s $dsize -W $timeout $host 2>&1)
		ba=`echo "$res" | grep "bad address"`
		[ -n "$ba" ] && { State=Error_CannotResolveHostName; return; }
		ba=`echo "$res" | grep "unknown host"`
		[ -n "$ba" ] && { State=Error_CannotResolveHostName; return; }
		stc=`echo "$res" | grep "received"`
		[ -z "$stc" ] && { State=Error_Other; return; }
		times=`echo "$res" | grep "min/avg/max"`
		[ -z "$times" ] && continue
		sc1=`echo $stc | awk '{print $4}'`
		sc1=${sc1:-0}
		success_count=$((success_count+sc1))
		times=`echo $times | awk -F'=' '{ print $2 }'`
		min_time=`echo $times | awk -F'[=/ ]' '{ print $1 }'`
		avg_time=`echo $times | awk -F'[=/ ]' '{ print $2 }'`
		max_time=`echo $times | awk -F'[=/ ]' '{ print $3 }'`
		min_time=${min_time:-0}
		avg_time=${avg_time:-0}
		max_time=${max_time:-0}
		min_time_d=`echo "$min_time * 1000" | bc -l`
		avg_time_d=`echo "$avg_time * 1000" | bc -l`
		max_time_d=`echo "$max_time * 1000" | bc -l`
		min_time_d=${min_time_d%.*}
		avg_time_d=${avg_time_d%.*}
		max_time_d=${max_time_d%.*}
		min_time=${min_time%.*}
		avg_time=${avg_time%.*}
		max_time=${max_time%.*}
		[ $min_time_d -lt $min_d ] && min_d=$min_time_d
		[ $max_time_d -gt $max_d ] && max_d=$max_time_d
		avg_time_sum_d=$((avg_time_sum_d+avg_time_d))

		[ $min_time -lt $min ] && min=$min_time
		[ $max_time -gt $max ] && max=$max_time
		avg_time_sum=$((avg_time_sum+avg_time))
	done
	failure_count=$((cnt-success_count))
	[ $success_count -gt 0 ] && avg_time=$((avg_time_sum/success_count)) && avg_time_d=$((avg_time_sum_d/success_count)) || avg_time=0
	min_time=$min
	max_time=$max
	min_time_d=$min_d
	max_time_d=$max_d
}

event_dignostic() {
	local e=1
	local i=0
	while [ "$e" != 0 -a $i -lt 200 ]; do	
		ubus -t 1 call tr069 inform '{"event":"8 DIAGNOSTICS COMPLETE"}'
		e=$?
		[ "$e" != "0" ] && sleep 1;
		let i++
	done
}

ipping_stop() {
	local pids=`ps aux | grep ipping_launch | grep -v grep | grep -v stop | awk '{print $2}'`
	[ -z "$pids" ] && pids=`ps | grep ipping_launch | grep -v grep | grep -v stop | awk '{print $2}'`
	if [ -n "$pids" ]; then
		kill -9 $pids 2>/dev/null
		$UCI_SET_VARSTATE easycwmp.@local[0].DiagnosticsState=None
	fi
}

[ "$1" == "run" ] && { ipping_run 2>/dev/null; exit 0; }
[ "$1" == "stop" ] && ipping_stop 2>/dev/null

