#!/bin/sh

. /etc/PG.conf

PING_CONF="${PGETC}/web/pingmonitor.conf"
PING_LIST="${PGETC}/web/pingmonitor.list"

RAMDISK="/usr/ramdisk"
FLOWEYE="${RAMDISK}/bin/floweye"
MSGPUSH="${RAMDISK}/bin/ipe_msgpush"

if [ "${NTM}" = "1" ]; then
    WORKDIR="/usr/ntmlog/pingmonitor"
else
    WORKDIR="${RAMDISK}/tmp/pingmonitor"
fi

LOGDIR="${DATAPATH}/App/pingmonitor/"
fapi_data="${WORKDIR}/ping_data.json"
fapi_time="${WORKDIR}/ping_time.json"
fapi_notice="${LOGDIR}/error_notice.log"


is_ipaddr()
{
    is_ipv6=`echo "${1}" | grep ":"`
    [ "${is_ipv6}" != "" ] && return 0

    echo "${1}" | grep "^[0-9]\{1,3\}\.\([0-9]\{1,3\}\.\)\{2\}[0-9]\{1,3\}$" > /dev/null;
    [ $? -ne 0 ] && return 1

    uipaddr=$1
    a=`echo $uipaddr|awk -F . '{print $1}'`
    b=`echo $uipaddr|awk -F . '{print $2}'`
    c=`echo $uipaddr|awk -F . '{print $3}'`
    d=`echo $uipaddr|awk -F . '{print $4}'`

    for num in $a $b $c $d
    do
        [ $num -gt 255 ] || [ $num -lt 0 ] && return 1
    done

    return 0
}


nslookup_url()
{
    url=$1
    dns=`cat /etc/resolv.conf | grep "^nameserver" | head -1 | cut -d" " -f2`
    [ "${dns}" = "" -o "${dns}" = "0.0.0.0" ] && dns="114.114.114.114"

    ${FLOWEYE} nslookup ${url} ${dns} | head -1
}


delete_ping_conf()
{
    #ҪPing·ڣɾ
    
    WEBUICTL="${RAMDISK}/app/webui/appctrl"

    grep -v " pxy_id=${1} " ${PING_LIST} > ${PING_LIST}.bak
    mv ${PING_LIST}.bak ${PING_LIST}

    ${WEBUICTL} start ping_monitor >/dev/null 2>&1 &
    exit 0
}


save_notice_log()
{
	[ ! -f ${fapi_notice} ] && touch ${fapi_notice}
	
	rows=`awk 'END{print NR}' ${fapi_notice}`
    
    if [ `uname` = "FreeBSD" ]; then
        times=`date -r ${1} "+%Y-%m-%d %H:%M:%S"`
    else
        times=`date -d @"${1}" "+%Y-%m-%d %H:%M:%S"`
    fi

	log="${1},${2},${3},${4},${times}"

	if [ ${rows} -ge 2000 ]; then
		echo ${log} > ${fapi_notice}
	else
		echo ${log} >> ${fapi_notice}
	fi
}


#׼л
mkdir -p ${LOGDIR}
mkdir -p ${WORKDIR}
rm -rf ${WORKDIR}/*

[ ! -f "${PING_CONF}" ] && exit 0
[ ! -f "${PING_LIST}" ] && exit 0

while read line
do
    export "g_${line}"
done <<EOF
`cat ${PING_CONF}`
EOF

[ "${g_ping_enable}" != "1" ] && exit 0

do_ping_times=0 #¼Ѿping˶ٴ
my_start_time=`date +%s` #¼ʱ

g_notice_interval=$((${g_notice_interval} * 60)) #澯֪ͨʱ

#ѭ
while true
do
    # ﵽPing
    if [ ${do_ping_times} -ge ${g_ping_max} ]; then
        rm -rf ${WORKDIR}/*
        do_ping_times=0
        my_start_time=`date +%s`
    fi

    do_ping_times=$((${do_ping_times} + 1))
    printf "{\"none\":\"none\"" > ${fapi_data}.bak

    cat ${PING_LIST} | while read line
    do
        for val in ${line}
        do
            export "api_${val}"
        done

        api_cur_delay=0
        api_ping_miss=0
        api_miss_rate=0
        api_tol_delay=0
        api_avg_delay=0
        api_max_delay=0
        api_min_delay=9999
        api_err_times=0
        api_notice_time=0
        have_error_notice=0
        obj_stat_file="${WORKDIR}/api_${api_id}.stat"

        # ʷ״̬
        [ -f ${obj_stat_file} ] && . ${obj_stat_file}

        # ȡǰʱ
        if [ "${api_pxy_id}" = "0" ]; then
            cur_delay=`${RAMDISK}/bin/ping ${api_obj} -s`
            [ $? -ne 0 ] && cur_delay=0
        else
            is_ipaddr ${api_obj}
            [ $? = "1" ] && api_obj=`nslookup_url ${api_obj}`
            cmdargs="if=${api_pxy_id} ip=${api_obj} count=1"
            [ "${api_nexthop}" != "" ] && cmdargs="${cmdargs} nexthop=${api_nexthop}"
            errmsg=`${FLOWEYE} ping ${cmdargs}`
            if [ "${errmsg}" = "SEND: NO_PXY" ]; then #Ping·
                delete_ping_conf ${api_pxy_id}
                continue 
            fi
            cur_delay=`echo "${errmsg}" | cut -d" " -f6 | cut -d"=" -f2 | sed 's/ms//g'`
        fi
        
        # жϷؽǷΪ
        api_cur_delay=${cur_delay}
        isnum=`echo "${cur_delay}" | grep -E "[a-zA-Z]"`
        [ "${isnum}" != "" -o "${cur_delay}" = "" ] && api_cur_delay=0

        # ͳƶ/ʱ״̬
        if [ "${api_cur_delay}" = "0" ]; then
            api_ping_miss=$((${api_ping_miss} + 1))
        else
            # ʱ
            api_tol_delay=`awk \
            -v tol=${api_tol_delay} -v cur=${api_cur_delay} \
            'BEGIN{
                tol = tol + cur;
                print tol;
            }'`

            # ƽʱ
            api_avg_delay=`awk \
            -v tol=${api_tol_delay} -v num=$((${do_ping_times} - ${api_ping_miss})) \
            'BEGIN{
                avg = sprintf("%.3f", tol / num);
                print avg
            }'`

            # ʱ
            api_max_delay=`awk \
            -v max=${api_max_delay} -v cur=${api_cur_delay} \
            'BEGIN{
                if(cur >= max)
                    print cur;
                else
                    print max;
            }'`

            # Сʱ
            api_min_delay=`awk \
            -v min=${api_min_delay} -v cur=${api_cur_delay} \
            'BEGIN{
                if(cur < min)
                    print cur;
                else
                    print min;
            }'`
        fi

        # 
        api_miss_rate=`awk \
        -v all=${do_ping_times} -v miss=${api_ping_miss} \
        'BEGIN{
            rate = sprintf("%.2f", miss/all*100);
            print rate;
        }'`

        # web APIӿļ
        printf ",\"api_${api_id}\":{" >> ${fapi_data}.bak
        printf "\"cur\":${api_cur_delay}" >> ${fapi_data}.bak
        printf ",\"avg\":${api_avg_delay}" >> ${fapi_data}.bak
        printf ",\"max\":${api_max_delay}" >> ${fapi_data}.bak
        printf ",\"min\":${api_min_delay}" >> ${fapi_data}.bak
        printf ",\"rate\":${api_miss_rate}" >> ${fapi_data}.bak
        printf ",\"miss\":${api_ping_miss}" >> ${fapi_data}.bak
        printf "}" >> ${fapi_data}.bak

        # ʵʱ״̬
        echo "api_cur_delay=${api_cur_delay}" > ${obj_stat_file}
        echo "api_ping_miss=${api_ping_miss}" >> ${obj_stat_file}
        echo "api_tol_delay=${api_tol_delay}" >> ${obj_stat_file}
        echo "api_avg_delay=${api_avg_delay}" >> ${obj_stat_file}
        echo "api_max_delay=${api_max_delay}" >> ${obj_stat_file}
        echo "api_min_delay=${api_min_delay}" >> ${obj_stat_file}
        echo "api_miss_rate=${api_miss_rate}" >> ${obj_stat_file}

        # 澯
        [ "${g_warring_enable}" = "0" ] && continue
        [ "${g_warring_object}" = "some" -a "${api_warring}" = "0" ] && continue

        error_happen=0
        need_notice=0

        error_happen=`awk \
        -v cur_delay=${api_cur_delay} -v set_delay=${g_warring_delay} \
        -v miss_rate=${api_miss_rate} -v set_miss_rate=${g_warring_miss} \
        'BEGIN{
            if(cur_delay == 0 || cur_delay >= set_delay || miss_rate >= set_miss_rate)
                print 1;
            else
                print 0;
        }'`

        if [ "${error_happen}" = "1" ]; then
            api_err_times=$((${api_err_times} + 1))
            #ﵽ쳣ȻжǷҪ͸澯
            if [ ${api_err_times} -ge ${g_warring_maxerror} ]; then
                if [ "${g_notice_type}" = "interval" ]; then
                    _diff=$((`date +%s` - ${api_notice_time}))
                    [ ${_diff} -ge ${g_notice_interval} ] && need_notice=1
                else
                    [ "${api_notice_time}" = "0" ] && need_notice=1
                fi
            fi
        else
            api_err_times=0
            api_notice_time=0
            # ָ֪ͨ
            if [ ${have_error_notice} = "1" ]; then
                msg_ctx=""
                msg_ctx="${msg_ctx}澯:е%0a"
                msg_ctx="${msg_ctx}澯:${g_warring_maxerror}δ${g_warring_delay}ms0ms򶪰ʴ${g_warring_miss}%%0a"
                msg_ctx="${msg_ctx}澯:${pxy_name}Ping${api_desc}[${api_obj}]ʱ${api_cur_delay}ms${api_miss_rate}%%0a"
                msg_ctx="${msg_ctx}ǰʱ:${api_cur_delay}ms${api_miss_rate}%%0a"
                msg_ctx="${msg_ctx}:${api_err_times}%0a"

                ${MSGPUSH} -s msg_title="Ping澯ѻָ" msg_ctx="${msg_ctx}"
                have_error_notice=0
            fi
        fi

        if [ "${need_notice}" = "1" ]; then
            api_notice_time=`date +%s`
            if [ "${api_pxy_id}" = "0" ]; then
                pxy_name=""
            else
                pxy_name=`${FLOWEYE} nat getproxy ${api_pxy_id} | grep ^name= | cut -d"=" -f2`
            fi

            msg_ctx=""
            msg_ctx="${msg_ctx}澯:е%0a"
            msg_ctx="${msg_ctx}澯:${g_warring_maxerror}δ${g_warring_delay}ms0ms򶪰ʴ${g_warring_miss}%%0a"
            msg_ctx="${msg_ctx}澯:${pxy_name}->${api_obj}ʱ${api_cur_delay}ms${api_miss_rate}%%0a"
            msg_ctx="${msg_ctx}ǰʱ:${api_cur_delay}ms${api_miss_rate}%%0a"
            msg_ctx="${msg_ctx}:${api_err_times}%0a"

            ${MSGPUSH} -s msg_title="Ping%20${api_desc}%20澯Ѵ" msg_ctx="${msg_ctx}"

            # ¼澯־ڴֻ2000
			save_notice_log "${api_notice_time}" "${pxy_name}" "${api_obj}[${api_desc}]" "${msg_ctx}"
			
            # 쳣֪ͨ¼
            have_error_notice=1
        fi

        echo "have_error_notice=${have_error_notice}" >> ${obj_stat_file}
        echo "api_err_times=${api_err_times}" >> ${obj_stat_file}
        echo "api_notice_time=${api_notice_time}" >> ${obj_stat_file}
    done

    printf "}" >> ${fapi_data}.bak
    mv ${fapi_data}.bak ${fapi_data}

    # Ping״̬
    printf "{" > ${fapi_time}.bak
    printf "\"do_ping_times\":${do_ping_times}" >> ${fapi_time}.bak
    printf ",\"my_start_time\":${my_start_time}" >> ${fapi_time}.bak
    printf "}" >> ${fapi_time}.bak
    mv ${fapi_time}.bak ${fapi_time}

    sleep ${g_ping_sleep}
done
