#!/bin/sh

IBPATH=${IBPATH:-@IBSCRIPTPATH@}

usage() {
	echo Usage: `basename $0` "[-h] [-b] [-v] [-G] [-T <threshold_file>]" \
	    "[-s(how_thresholds)] [-N \| -nocolor] [-C ca_name] [-P ca_port]" \
	    "[-t(imeout) timeout_ms] <lid|guid> [<port>]"
	exit 255
}

green() {
	if [ "$bw" = "yes" ]; then
		if [ "$verbose" = "yes" ]; then
			echo $1
		fi
		return
	fi
	if [ "$verbose" = "yes" ]; then
		echo -e "\\033[1;032m" $1 "\\033[0;39m"
	fi
}

red() {
	if [ "$bw" = "yes" ]; then
		echo $1
		return
	fi
	echo -e "\\033[1;031m" $1 "\\033[0;39m"
}

show_thresholds() {
	echo "SymbolErrorCounter=$SymbolErrorCounter"
	echo "LinkErrorRecoveryCounter=$LinkErrorRecoveryCounter"
	echo "LinkDownedCounter=$LinkDownedCounter"
	echo "PortRcvErrors=$PortRcvErrors"
	echo "PortRcvRemotePhysicalErrors=$PortRcvRemotePhysicalErrors"
	echo "PortRcvSwitchRelayErrors=$PortRcvSwitchRelayErrors"
	echo "PortXmitDiscards=$PortXmitDiscards"
	echo "PortXmitConstraintErrors=$PortXmitConstraintErrors"
	echo "PortRcvConstraintErrors=$PortRcvConstraintErrors"
	echo "LocalLinkIntegrityErrors=$LocalLinkIntegrityErrors"
	echo "ExcessiveBufferOverrunErrors=$ExcessiveBufferOverrunErrors"
	echo "VL15Dropped=$VL15Dropped"
}

get_thresholds() {
	. $1
}

# Default thresholds
SymbolErrorCounter=10
LinkErrorRecoveryCounter=10
LinkDownedCounter=10
PortRcvErrors=10
PortRcvRemotePhysicalErrors=100
PortRcvSwitchRelayErrors=100
PortXmitDiscards=100
PortXmitConstraintErrors=100
PortRcvConstraintErrors=100
LocalLinkIntegrityErrors=10
ExcessiveBufferOverrunErrors=10
VL15Dropped=100

guid_addr=""
bw=""
verbose=""
brief=""
ca_info=""
suppress_deprecated="no"

while [ "$1" ]; do
	case $1 in
	-G)
		guid_addr=yes
		;;
	-nocolor|-N)
		bw=yes
		;;
	-v)
		verbose=yes
		brief=""
		;;
	-b)
		brief=yes
		verbose=""
		;;
	-T)
		if ! [ -r $2 ]; then
			echo "Can't use threshold file '$2'"
			usage
		fi
		get_thresholds $2
		shift
		;;
	-s)
		show_thresholds
		exit 0
		;;
	-S)
		suppress_deprecated="yes"
		;;
	-P | -C | -t | -timeout)
		case $2 in
		-*)
			usage
			;;
		esac
		if [ x$2 = x ] ; then
			usage
		fi
		ca_info="$ca_info $1 $2"
		shift
		;;
	-*)
		usage
		;;
	*)
		break
		;;
	esac
	shift
done

#default is all ports
portnum=255

if [ $# -lt 1 ]; then
	usage
fi

if [ "$2" ]; then
	portnum=$2
fi

if [ "$portnum" = "255" ]; then
	portname="all"
else
	portname=$2
fi

if [ "$suppress_deprecated" = "no" ]; then
/usr/bin/echo -e "*** WARNING ***: this command is deprecated; Please use \"ibqueryerrors\"\n\n" 1>&2
fi

if [ "$guid_addr" ]; then
	if ! lid=`$IBPATH/ibaddr $ca_info -G -L $1 | awk '/failed/{exit 255} {print $3}'`; then
		echo -n "guid $1 address resolution: "
		red "FAILED"
		exit 255
	fi
	guid=$1
else
	lid=$1
	if ! temp=`$IBPATH/ibaddr $ca_info -L $1 | awk '/failed/{exit 255} {print $1}'`; then
		echo -n "lid $1 address resolution: "
		red "FAILED"
		exit 255
	fi
fi

nodename=`$IBPATH/smpquery $ca_info nodedesc $lid | sed -e "s/^Node Description:\.*\(.*\)/\1/"`

text="`eval $IBPATH/perfquery $ca_info $lid $portnum`"
rv=$?
if echo $text | grep -q 'AllPortSelect not supported'; then
	if [ "$verbose" = "yes" ]; then
		echo -n "Error check on lid $lid ($nodename) port $portname: "
		green "AllPortSelect not supported"
	fi
	exit 0
fi

if echo "$text" | awk -v mono=$bw -v brief=$brief -F '[.:]*' '
function blue(s)
{
	if (brief == "yes") {
		return
	}
	if (mono)
		printf s
	else if (!quiet) {
		printf "\033[1;034m" s
		printf "\033[0;39m"
	}
}

BEGIN {
	th["SymbolErrorCounter"] = '$SymbolErrorCounter'
	th["LinkErrorRecoveryCounter"] = '$LinkErrorRecoveryCounter'
	th["LinkDownedCounter"] = '$LinkDownedCounter'
	th["PortRcvErrors"] = '$PortRcvErrors'
	th["PortRcvRemotePhysicalErrors"] = '$PortRcvRemotePhysicalErrors'
	th["PortRcvSwitchRelayErrors"] = '$PortRcvSwitchRelayErrors'
	th["PortXmitDiscards"] = '$PortXmitDiscards'
	th["PortXmitConstraintErrors"] = '$PortXmitConstraintErrors'
	th["PortRcvConstraintErrors"] = '$PortRcvConstraintErrors'
	th["LocalLinkIntegrityErrors"] = '$LocalLinkIntegrityErrors'
	th["ExcessiveBufferOverrunErrors"] = '$ExcessiveBufferOverrunErrors'
	th["VL15Dropped"] = '$VL15Dropped'
}

/^CounterSelect/ {next}

/AllPortSelect/ {next}

/^ib/  {print $0; next}
/ibpanic:/     {print $0}
/ibwarn:/      {print $0}
/iberror:/     {print $0}

/^PortSelect/	{ if ($2 != '$portnum') {err = err "error: lid '$lid' port " $2 " does not match query ('$portnum')\n"; exit 255}}

$1 ~ "(Xmt|Rcv)(Pkts|Data)" { next }

	{ if (th[$1] > 0 && $2 >= th[$1])
		warn = warn "#warn: counter " $1 " = " $2 " \t(threshold " th[$1] ") lid '$lid' port '$portnum'\n"
	}
END {
	if (err != "") {
		blue(err)
		exit 255
	}
	if (warn != "") {
		blue(warn)
		exit 255
	}
	exit 0
}' 2>&1 && test $rv -eq 0 ; then
	if [ "$verbose" = "yes" ]; then
		echo -n "Error check on lid $lid ($nodename) port $portname: "
		green OK
	fi
	exit 0
else
	echo -n "Error check on lid $lid ($nodename) port $portname: "
	red FAILED
	exit 255
fi
