#!/bin/bash

#started from startup|shutdown|ssh|shell|cmon , etc.
MYFROM=$1
if [ -z "$MYFROM" ] ; then MYFROM=shell ; fi
GNC_FROM=$MYFROM;
export GNC_FROM;

. /usr/share/groovix/global.conf

#in case filter is in place
unset http_proxy
unset https_proxy


#################################################################################
# functions
#############################################################################################

function depends-checker () {

for F in $(find $UPDIR/*/*/*/depends -name unmet 2>/dev/null) ; do
        local ND=$(dirname $F)
        local NAME=$(basename $ND)
        local GD=$(dirname $ND)
        local GNAME=$(basename $GD)
        local VD=$(dirname $GD)
        local VNAME=$(basename $VD)
        #echo
        #echo $F
        #echo $VNAME $GNAME $NAME

        local SAVEDRUN=$(cat $F 2>/dev/null)
        local LASTRUN=$(cat $UPDIR/$VNAME/$GNAME/$NAME/lastorder 2>/dev/null)

        if [ -f "$UPDIR/$VNAME/$GNAME/$NAME/success" ] ; then
                echo "GNC COMPLETION CHECK : dependency $F is newly met"       
                return 1
        fi

done

echo GNC COMPLETION CHECK : no newly met depenencies
return 0


}

function overrides-checker () {

for F in $(find $UPDIR/*/*/*/overrides -name lastorder 2>/dev/null) ; do
        local ND=$(dirname $F)
        local NAME=$(basename $ND)
        local GD=$(dirname $ND)
        local GNAME=$(basename $GD)
        local VD=$(dirname $GD)
        local VNAME=$(basename $VD)
        #echo
        #echo $F
        #echo $VNAME $GNAME $NAME

        local SAVEDRUN=$(cat $F 2>/dev/null)
        local LASTRUN=$(cat $UPDIR/$VNAME/$GNAME/$NAME/lastorder 2>/dev/null)

        if [ "$SAVEDRUN" = "$LASTRUN" ] ; then
                echo "GNC overridden order match for $F"
        else    
                #echo "overridden order mismatch for $VNAME/$GNAME/$NAME :  saved= $SAVEDRUN current= $LASTRUN"
                echo "GNC COMPLETION CHECK : overridden order mismatch for $F :  saved= $SAVEDRUN current= $LASTRUN"
                return 1
        fi
        
done 

echo GNC COMPLETION CHECK : no overrides need to run
return 0

}



function get-update-list () {

################################################################################
#grab updates
################################################################################

#dont move old net update script copies out of the way
#leave cached versions
#rm -f /var/lib/groovix/net-control/master.bash
#rm -f /var/lib/groovix/net-control/local_master.bash

#now we want to remove individual server exec lists, but leave the final master cached in case of no network
rm -f /var/lib/groovix/net-control/master-*.bash
rm -f /var/lib/groovix/net-control/master-*.url
rm -f /var/lib/groovix/net-control/non-gnc-process-sorted.bash
rm -f /var/lib/groovix/net-control/gnc-process-sorted.bash


	##############################################################
	# gather workstation info
	##############################################################
	#log ips
	MYIP=`groovix-find-active-ip-address`
	#not used for anything# echo $MYIP > /etc/groovix/local_ip
	
	OSVERSION=$(groovix-get-parameter GX_OSVERSION)
	
	GVERSION=$(groovix-get-parameter GX_VERSION)
	
	GSITE=$(groovix-get-parameter GX_SITE)
	
	GLABEL=$(groovix-get-parameter GX_LABEL)
	
	GTYPES=$(groovix-get-parameter GX_TYPES)
	
	GTYPESTRING="";
	for T in $GTYPES ; do
		GTYPESTRING="${GTYPESTRING}&types[]=$T"
	done


	#implicit in groovix-wget is --tries=2 --timeout=60 , so at most a failed request can take 2 minutes

	#for I in $(seq 0 $((${#GNC_SERVER_URLS[@]} - 1))) ; do
	for I in ${!GNC_SERVER_URLS[@]} ; do
	echo "GNC processing server # $I"
	WGETLCOUNT=0
	WGETLRC=1
        if [ -n "${GNC_SERVER_URLS[$I]}" ] ; then
		while [ $WGETLRC -ne 0 ] && [ $WGETLCOUNT -lt 1 ] ; do
			MYURL="${GNC_SERVER_URLS[$I]}?id=$GSN&ip=$MYIP&os=$OSVERSION&version=$GVERSION&site=$GSITE&label=$GLABEL$GTYPESTRING"
			echo "$MYURL" > /var/lib/groovix/net-control/master-$I.url
			#check for cache
			diff /var/lib/groovix/net-control/master-$I.url /var/lib/groovix/net-control/master-$I.url-cached > /dev/null 2>&1
			if [ $? -eq 0 ] ; then
				echo "GNC using cached update list from ${GNC_SERVER_URLS[$I]}"
				cp /var/lib/groovix/net-control/master-$I.bash-cached /var/lib/groovix/net-control/master-$I.bash
				WGETLRC=0
			else
				echo "GNC downloading update list from ${GNC_SERVER_URLS[$I]}"
				groovix-wget $MYURL /var/lib/groovix/net-control/master-$I.bash --no-verbose  ;  #2>/dev/null
				WGETLRC=$?
			fi
			if [ $WGETLRC -eq 0 ] ; then
				#cache things for subsequent passes
				echo "$MYURL" > /var/lib/groovix/net-control/master-$I.url-cached
				cp /var/lib/groovix/net-control/master-$I.bash /var/lib/groovix/net-control/master-$I.bash-cached 
				#which server was this from (no need to have server this info send it like in the past)
				sed -i "s/gnc-process /gnc-process --server $I /" /var/lib/groovix/net-control/master-$I.bash
			fi
			let WGETLCOUNT++
		done
	fi
	done

	ls /var/lib/groovix/net-control/master-*.bash  > /dev/null 2>/dev/null
	if [ $? -eq 0 ] ; then
		#setting LC_ALL is necessary to get sort to behave the way we'd expect - we want 123a to come AFTER 123
		# for now we sort alphanumerically so order is 2000 , 20130404 , 9600 : the same way gnc worked before GNC_ORDER was implemented
		# we really don't care about order between versions and types, etc. but lets sort on it so its consistent and doesn't change from run to run
		export LC_ALL=C
		egrep --no-filename "^gnc-process"  /var/lib/groovix/net-control/master-*.bash | sort -k5,5 -k7,7 -k3,3r -k9,9 -k11,11 > /var/lib/groovix/net-control/gnc-process-sorted.bash
		# other things that got put into master*.bash files, like bashconfset lines, variable definitions, etc.
		# sort them by standard sort just so they end up in a predictable order
		egrep --no-filename -v "^gnc-process" /var/lib/groovix/net-control/master-*.bash | sort > /var/lib/groovix/net-control/non-gnc-process-sorted.bash
		
		cat /var/lib/groovix/net-control/header.bash /var/lib/groovix/net-control/non-gnc-process-sorted.bash /var/lib/groovix/net-control/gnc-process-sorted.bash > /var/lib/groovix/net-control/master.bash
	else
		echo "GNC using cached copy of master.bash"
	fi

	chmod 770 /var/lib/groovix/net-control/master.bash

}

#################################################################################################
# main gnc 
#################################################################################################

GNCDIR=/var/lib/groovix/net-control/
UPDIR=$GNCDIR/updates/

if [ -z "${GNC_SERVER_URLS[0]}" ] ; then
	GNC_SERVER_URLS[0]="http://u2013.groovix.net/bin/getupdates.php"
fi

#LOOK FOR COMMAND LINE gncdisable OVERRIDE
grep -q gncdisable /proc/cmdline
if [ $? -eq 0 ] ; then
        GNC_DISABLE="true";
fi

if [ "$GNC_DISABLE" = "true" ] ; then
	echo  ########################################################
	echo "GNC groovix-net-control is disabled and will not run"
	echo  ########################################################
	exit 23
fi

#############################################################
# unlock some lockdowns that can cause problems
#############################################################
mount -o remount,exec /tmp

echo
echo
echo "GNC Beginning Groovix Net Control at `date`"
echo
echo


	######################################################################
	#insert random delay to prevent bandwidth surge at big sites and add end delay
	CLOSEDELAY=0
	if [ "$MYFROM" = "startup" ] ; then
		CURDELAY=$GNC_MAX_RANDOM_DELAY_STARTUP
	elif [ "$MYFROM" = "closing" ] ; then
		# if we're triggered by the closing timer this isn't a quick reboot, do gnc again on next start
		touch /var/lib/groovix/net-control/force-on-startup
		CURDELAY=$GNC_MAX_RANDOM_DELAY_SHUTDOWN
	elif [ "$MYFROM" = "cron" ] ; then
		CURDELAY=$GNC_MAX_RANDOM_DELAY_SHUTDOWN
		# if we're triggered by cron this isn't a quick reboot, do gnc again on next start
		touch /var/lib/groovix/net-control/force-on-startup
	elif [ "$MYFROM" = "shutdown" ] ; then
		CURDELAY=$GNC_MAX_RANDOM_DELAY_SHUTDOWN
	elif [ "$MYFROM" = "ssh" ] ; then
		CURDELAY=1
	elif [ "$MYFROM" = "gam" ] ; then
		# from groovix-admin-menu
		CURDELAY=1
		CLOSEDELAY=30
	elif [ "$MYFROM" = "shell" ] ; then
		CURDELAY=1
	else
		CURDELAY=$GNC_MAX_RANDOM_DELAY
	fi

	if [ -z "$CURDELAY" ] ; then
		CURDELAY=30
	fi
	#not random enough - $RANDOM is initially seeded by date and process id - lots of machines booting up at once could all be the same
	#GNC_DELAY=$[ ( $RANDOM % $GNC_MAX_RANDOM_DELAY )  + 1 ]
	#echo ls -l /dev/urandom
	#ls -l /dev/urandom
	#echo head -c4 /dev/urandom | od -t u4 | awk '{ print $2 }'
	#head -c4 /dev/urandom | od -t u4 | awk '{ print $2 }'
	echo

	if [ "$GNC_DONT_RUN" = "true" ] ; then
		echo "GNC not delaying since GNC_DONT_RUN = true and master.bash will not be executed"
	else
		GNC_DELAY=$[ ( $(head -c4 /dev/urandom | od -t u4 | awk '{ print $2 }') % $CURDELAY ) ]
		echo "GNC Waiting $GNC_DELAY seconds before starting"
       		gnc-delay $GNC_DELAY
	fi
	######################################################################


##########################################
# groovix-pre-gnc-setup will get all of these values in place in their files, so we can just grab them.  if unset, send blank or unknown


#even if we're building from inside a live cd, we consider build mode to trump live mode
if [ -e /tmp/customization-scripts/groovix-build.conf ] ; then
        GSN=groovix-image-builder
else
	GSN=$(groovix-get-parameter GX_ID)
	#echo "GROOVIX ID number: $GSN" 
fi


#as automatic as possible
export DEBIAN_FRONTEND=noninteractive

#############################################################################################
### run Groovix server master
#############################################################################################
# GNC_DONT_RUN gets exported in some cases, i.e. just want a quick reboot
if [ "$GNC_DONT_RUN" != "true" ] ; then


	#dos2unix /var/lib/groovix/net-control/master.bash
	################################################################
	#set up environment
	export GNC_BACKGROUND
	################################################################


	#initial setup
	#touch to run at least once , will get removed inside of gnc
	touch /var/lib/groovix/net-control/rerun
	rm -f /var/lib/groovix/net-control/continue
	rm -f /var/lib/groovix/net-control/break
	rm -f /var/lib/groovix/net-control/reboot

	# on subsequent passes we might use cached version
	rm -f /var/lib/groovix/net-control/master*.url-cached
	rm -f /var/lib/groovix/net-control/master*.bash-cached



	MYCOUNT=0

	# run maximum 5 passes
	# break overrides rerun
	while [ $MYCOUNT -lt 5 ] && [ -f /var/lib/groovix/net-control/rerun ] && ! [ -f /var/lib/groovix/net-control/break ] ; do

		let MYCOUNT++

		echo
		echo '###################################################################################'
		echo "GNC running master.bash pass # $MYCOUNT"
		echo '###################################################################################'
		echo

		####################################################################################
		#get update list from server(s)
		#######################################################################
		get-update-list
		if  [ "$GNC_FROM"  = "update-list" ] ; then
			echo "got update list, exiting because --from = update-list"
			exit 0
		fi

		# start fresh
		rm -f /var/lib/groovix/net-control/rerun

		/var/lib/groovix/net-control/master.bash 

		# after each run clear continue flag that prevents other gncs from running in that pass
		rm -f /var/lib/groovix/net-control/continue

		echo
		[ -f /var/lib/groovix/net-control/rerun ] && echo "GNC COMPLETION CHECK : rerun triggered by an update"
		overrides-checker || touch /var/lib/groovix/net-control/rerun
		depends-checker || touch /var/lib/groovix/net-control/rerun
		[ -f /var/lib/groovix/net-control/break ] && echo "GNC COMPLETION CHECK : break triggered by an update"

	done
	echo
	echo GNC DONE RUNNING all passes of master.bash , pass count was $MYCOUNT
	echo


else
	echo "GNC not running /var/lib/groovix/net-control/master.bash"
fi

#done ; # for all update types

#make sure CLOSEDELAY is an integer > 0
if [ "$CLOSEDELAY" -gt 0 ] ; then
        TMOUT=$CLOSEDELAY    # Prompt times out at X seconds.
        echo "Waiting $CLOSEDELAY seconds so you can see the messages above,"
	echo "Hit Enter to proceed immediately ... "
        read whatever
fi



echo
if [ "$GNC_BACKGROUND" ] ; then
	echo GNC Background Groovix Net Control Complete
else
	echo GNC Groovix Net Control Complete
fi
echo

exit $WGETGRC


