#! /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/>.
# 
# }}}
#

# checknode now has two duties. gather/collect in MFS mode
# and run in normal mode so sub-programs can be called by sourcing,
# letting everthing run in the same shell. Sub-programs should 
# also be allowed to run standalone.

source checkutils.sh
set -u
set -e

nodecheck_main() {
    (( $check_flag )) && checks="time cpu mem nic disk" || checks="cpu mem nic disk"
    for i in $checks ; do
	source $BINDIR/${i}check $LOGDIR/nodecheck.log 
    done
    return 0
}


gatherinv_main() {

    echo -n '  Gathering Inventory..'
    (( ! $collect_flag )) && echo "Hmmm tmcc says not to collect. Doing so anyway."
    
    checks="disk cpu mem nic"
    for i in $checks ; do
	source $BINDIR/${i}check $LOGDIR/nodecheck.log 
    done
    return 0
}

postprocessing()
{
    timestamp=$(date +%y%m%d%H%M%S)

    if (( $collect_flag )) ; then

        # read in the newly found info into hwinv array
	readtmcinfo /tmp/nodecheck.log.tb hwinv

        # print it back out in tmcc hwinfo format
	{ printtmcinfo
} > /tmp/nodecheck.log.tb.new # .new not necessary should reuse old name
        # note what kernel we are running
	printf "# KERNEL %s\n" "$(uname -svrm)" >> /tmp/nodecheck.log.tb.new
	# add which mode we running as
	printf "# ismfs=%s %s nodetype %s \n" "$mfsmode" "$(getfromtb TESTINFO)" "$nodetype"  >> /tmp/nodecheck.log.tb.new
	printf "# Memory found is %s less then DB info of %s\n" "$slop" "$(getfromtb MEMINFO)" >> /tmp/nodecheck.log.tb.new

    # print the full listng of found inventory
	{ printhwinv
} > /tmp/nodecheck.log.inv
	printf "# KERNEL %s\n" "$(uname -svrm)" >> /tmp/nodecheck.log.inv
	# add which mode we running as
	printf "# ismfs=%s %s nodetype %s \n"  "$mfsmode" "$(getfromtb TESTINFO)" "$nodetype" >> /tmp/nodecheck.log.inv
	printf "# Memory found is %s less then DB info of %s method:%s\n" "$slop" "$(getfromtb MEMINFO)" "$memmethod" >> /tmp/nodecheck.log.inv
	printf "# DIMMs: Size %s slots %s empty slots %s\n" "$DIMMsize" "$DIMMslots" "$DIMMsempty"  >> /tmp/nodecheck.log.inv

    # make sure projdir is available
        if [ ! -d ${projdir} ] ; then
            dirn="${projdir%${projdir##*/}}"
            [[ "${dirn:=./}" != "/" ]] && dirn="${dirn%?}"
	    dirnmounted=$(df | grep $dirn)
	    if [ -n "$dirnmounted" ] ; then
    		if [ ! -d ${projdir} ] ; then
		    mkdir ${projdir}
    		    if [ ! -d ${projdir} ] ; then
			echo "Was not able to make $projdir...whats up with that"
			exit 1
		    else
			chmod 755 $projdir
		    fi
		fi
	    else
		echo "OHhh all this work for nothing $projdir not mounted can't save info"
		exit 1
	    fi
	fi

    # start XXX
    # decided to change names again, rename if old names -- XXX remove this after all node have run the new code
    # take into consideration if old directory structure was added to to a new directory structure 
	if [ -d ${projdir}/$host ] ; then
	    owd=$PWD
	    cd ${projdir}/$host
	    [[ -L $host.full ]] && rm $host.full
	    [[ -L $host.diff ]] && rm $host.diff
	    for i in full diff tbdb ; do
		if [ -d $i ] ; then
		    [[ ! -d .$i ]] && (mkdir .$i ; chmod g+x .$i)
		    list=$(ls -A $i)
		    for j in $list ; do
			mv $i/$j .$i
		    done
		    rmdir $i
		fi
	    done
	    cd $owd
	fi
    # end XXX

    # have needed dirs ?
	[[ ! -d ${projdir}/$host ]] && ( mkdir -p ${projdir}/$host ; chmod g+rwx ${projdir}/$host )
	[[ ! -d ${projdir}/$host/.tbdb ]] && ( mkdir -p ${projdir}/$host/.tbdb ; chmod g+rwx ${projdir}/$host/.tbdb )
	[[ ! -d ${projdir}/$host/.full ]] && ( mkdir -p ${projdir}/$host/.full ; chmod g+rwx ${projdir}/$host/.full )
	[[ ! -d ${projdir}/$host/.diff ]] && ( mkdir -p ${projdir}/$host/.diff ; chmod g+rwx ${projdir}/$host/.diff )
	[[ ! -d ${projdir}/$host/.tmcc ]] && ( mkdir -p ${projdir}/$host/.tmcc ; chmod g+rwx ${projdir}/$host/.tmcc )

    # copy over the files including timestamps
	cp /tmp/nodecheck.log.tb.new ${projdir}/$host/.tbdb/$timestamp
	cp /tmp/nodecheck.log.inv ${projdir}/$host/.full/$timestamp

    # offline checking can be done if the tmcc is saved
	owd=$PWD
	cd ${projdir}/$host
	# save what tmcc says right now
	$($BINDIR/tmcc hwinfo > ${projdir}/$host/.tmcc/$timestamp)
	ln -sf .tmcc/$timestamp ${projdir}/$host/tmcc
	cd $owd

    # remove old symlinks and make new ones
	owd=$PWD
	cd ${projdir}/$host
	[[ -L $host ]] && rm -f $host #this should be a symlink
	[[ -L node ]] && rm -f node #this should be a symlink
	[[ -L full ]] && rm -f full #another symlink
	[[ -L diff ]] && rm -f diff #another symlink
	ln -s .tbdb/${timestamp} ${projdir}/$host/$host
	ln -s .tbdb/${timestamp} ${projdir}/$host/node
	ln -s .full/$timestamp ${projdir}/$host/full
	cd $owd

    # make sure no sudo is needed for read
	chmod go+r ${projdir}/$host/.*/${timestamp}
    fi

    if (( $check_flag )) ; then
	cd ${projdir}/$host
	# save what tmcc says right now
	$($BINDIR/tmcc hwinfo > ${projdir}/$host/.tmcc/$timestamp)
	ln -sf .tmcc/$timestamp ${projdir}/$host/tmcc
	cd $owd

        # Test what was found locally against what is in the database
	readtmcinfo tmcc hwinvcopy # info from tmcc.bin hwinv
            # if testing can do something like    readtmcinfo ${projdir}/test
	readtmcinfo /tmp/nodecheck.log.inv hwinv # read full listing of locally found into hwinv
	# diff for local stuff not in tbdb
	comparetmcinfo /tmp/nodecheck.diff # file for output

        # if we ended up with a diff file handle it
	if [ -s /tmp/nodecheck.diff ] ; then
# show it at runtime??	cat /tmp/nodecheck.diff
	    # header
	    printf "\nDiff Report for %s @ %s\nKernel %s\n" "$host" "$(date)" "$(uname -srvm)" >> ${projdir}/$host/.diff/${timestamp}
	    echo "------------------------------------------------------------------" >> ${projdir}/$host/.diff/${timestamp}
	    # body
	    cat /tmp/nodecheck.diff >> ${projdir}/$host/.diff/${timestamp}
	    # link it
	    cd  ${projdir}/$host
	    [[ -L diff ]] && rm -f diff
	    ln -s .diff/${timestamp} ${projdir}/${host}/diff
	    cd $owd
	else
	    # no diff maybe it got better, put a marker out
	    cp /dev/null ${projdir}/${host}/.diff/${timestamp}
	fi
	chmod g+r ${projdir}/$host/.diff/${timestamp}
    fi

    [[ -f /tmp/nodecheck.log.inv ]] && rm /tmp/nodecheck.log.inv
    [[ -f /tmp/nodecheck.log.tb.new ]] && rm /tmp/nodecheck.log.tb.new 
    [[ -f /tmp/nodecheck.diff ]] && rm /tmp/nodecheck.diff

    return 0
}

initialize $@

(( $mfsmode )) && gatherinv_main $@ || nodecheck_main $@ 
postprocessing
