#!/bin/bash
#
# Copyright (c) 2013 University of Utah and the Flux Group.
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
#

echo -n ' Starting niccheck.. '

source checkutils.sh

x=$(caller)
[[ "${x/NULL}" = "$x" ]] && declare -ri niccheck_standalone=0 || declare -ri niccheck_standalone=1

declare failed=""

initialize $@
cp /dev/null $tmplog

tmplog2=/tmp/.2tmp
cp /dev/null ${tmplog2}
add_on_exit "rm -f $tmplog2"

finished() {
cat ${tmplog2}
echo "Niccheck `date`:" >> ${logfile}
cat ${tmplog} >> ${logfile} 
cat ${tmplog2} >> ${logfile} 
rm -f ${tmplog2}

(( $niccheck_standalone )) && exit 0 || return 0
}

{
unset -v ifinfo ; declare -a ifinfo=()
case $os in
    Linux )
	;;
    FreeBSD )
	;;
    * )
	failed="os $os unknown"
	finished
	;;
esac

# Ignore virtual devices that won't be in the DB
badboys="(ifb|xenbr|vlan|AMPR)"

unset -v d ; declare -a d=($(ifconfig -a | grep -e 'ether' -e 'HWaddr' | grep -Ev $badboys))
declare -i cnt=0;
ifinfo[0]=''
for ((idx=0; idx<${#d[*]};idx++)) ; do
    [[ "${d[idx]}" == "ether" || "${d[idx]}" == "HWaddr" ]] || continue
    ((++idx))
    y=${d[idx]}
    y=${y,,} #lowercase
    e=${y//:/}
    # don't place on list if dup. can happen with vlan interface
    list=${ifinfo[@]}
    for i in $list ; do
	[[ "$i" == "$e" ]] && e=''
    done
    [[ "$e" ]] && { ifinfo[$cnt]=${e} ; ((++cnt)) ; }
done

echo "${ifinfo[@]}"

} >> ${tmplog} 2>&1

ifcnt=${#ifinfo[*]}

# if saving data for testbed database
if (( $collect_flag ))  ; then
    printf "NETINFO UNITS=%s\n"  ${ifcnt} >> ${logfile4tb}
    for ((ifi=0; ifi<$ifcnt; ifi++)) ; do
	macl="${ifinfo[$ifi]}"
	macl=${macl,,}
	printf "NETUNIT TYPE=\""ETH\"" ID=\""%s\""\n" ${ifinfo[$ifi]} >> ${logfile4tb}
    done
fi

# we are done if in MFS mode
if (( $mfsmode )) ; then
    (( $niccheck_standalone )) && exit 0 || return 0
fi

tbreturn=$(getfromtb NETUNIT)
if [ -z "$tbreturn" ] ; then 
    failed="TBmiss no info"
    $(echo "TBmiss empty info returned. Have ${ifinfo[@]} FAILED" >> ${tmplog2})
    finished
fi

#lowercase
tbreturn=${tbreturn,,}

#turn space seperated string into array
unset -v tbinfo; declare -a tbinfo=(${tbreturn// / })

tbcnt=${#tbinfo[*]}
numnics=$ifcnt
maxcnt=${ifcnt}


if [[ ${ifcnt} -ne ${tbcnt} ]] ; then
    failed="TBmiss"
    [[ ${ifcnt} -gt ${tbcnt} ]] && maxcnt=${ifcnt} || maxcnt=${tbcnt}
fi

for ((idx=0; idx<$maxcnt; idx++)) ; do
    for ((ifi=0; ifi<$ifcnt; ifi++)) ; do
	for ((tbi=0; tbi<$tbcnt; tbi++)) ; do
	    if [ "${ifinfo[$ifi]}" = "${tbinfo[$tbi]}" ] ; then
		ifinfo[$ifi]=''
		tbinfo[$tbi]=''
	    fi
	done
    done
done
ifresult=${ifinfo[@]}
tbresult=${tbinfo[@]}

#	    failed="$failed TB missing nic "
#	    failed="$failed TB extra nic "

if [[ ! "$ifresult" && ! "$tbresult" ]] ; then
    if [[ $ifresult ]] ; then
	failed="${failed}: NotIn TB $ifresult"
    fi
    if [[ $tbresult ]] ; then
	failed="${failed}: TB Claims $tbresult"
    fi
fi


{
    [[ -z ${failed} ]] && echo "$numnics interfaces OK" || echo "$numnics interfaces $failed" FAILED

} >> ${tmplog2} 2>&1


finished

(( $niccheck_standalone )) && exit 0 || return 0

