#!/bin/bash

#Resize window to 40x125 t
printf '\e[8;40;125t'

## Fornat Helper
#echo ${a_vmName[0]}
#vboxmanage startvm <name or UUID>
#39452eea-9c96-42a4-9acd-68ad45b93236
#5a55df71-41cc-4147-ac22-3012f7252650

## Aliasing
vbm='/usr/local/bin/VBoxManage'
srp='/Users/admin/usr/vlu'
etc=$(echo $srp'/etc')
log=$(echo $srp'/logs/vmManager.log')

DATE=$(date); echo $DATE >> $log

###################
## Functions #####
################

function help () {
	echo -e "vmmanager\tVM Orchestrator to keep the VM running if registered as such."
	echo -e "\thelp\tDisplay this help message"
	echo -e "\tlist\tList Managed VMs and their status + Desired state"
	echo -e "\taddvm\tAdd given VM name to the list (UUID will be defined and matched automatically)"
	echo -e "\tdelvm\tRemove given VM from the list"
	echo -e "\tstopvm|restartvm|startvm|resetvm\n\t\tStop|Restart|Start|Reset given VM name/UUID (Headless)"
	exit 0;
}

function logger () {
	echo -e >> $log
	if [[ $sec_option != 'silence' ]]; then echo -e $1;fi
}

function stopvm () {
	eval $vbm controlvm $1 poweroff
}

function resetvm () {
	eval $vbm controlvm $1 reset
}

function startvm () {
	eval $vbm startvm $1 --type headless
}

function restartvm () {
	stopvm $1
	startvm $1
}

function powerOffAll () {
	for i in "${!a_list_vmName[@]}"
	do
		vmName=${a_list_vmName[i]}
		vmInfoState=$(eval $vbm showvminfo $vmName | grep -i state | grep running -c)
		if [[ $vmInfoState -gt 0 ]]; then
			echo -ne "Powering Off VM ["$vmName"] "
	    	stopvm $vmName			
		else
			echo -e "VM ["$vmName"] is not running, no need to shut it down"
		fi
	done
}

function meantRunning_startvm () {
	#VM is not running and we need to start it if we find it into the file
	associatedVMName=$(grep "$vmIDTrimmed" $etc'/active_vmlist' | awk '{print $2}')
	isVMPowered_dsp='False'

	if [[ $isMeantRunning -eq 1 ]]; then
		if [[ $sec_option != "silence" ]]; then
			logger "VM ["$associatedVMName"] with ID "$vmID" has been found and should be running"
		fi

		# Start VM process
		startvm $vmIDTrimmed

		vmInfoState=$(eval $vbm showvminfo $associatedVMName | grep -i state | grep running -c)
		if [[ $vmInfoState -gt 0 ]]; then
			isVMPowered_dsp='True'
		fi
	else
		if [[ $sec_option != "silence" ]]; then
			logger "VM ["$associatedVMName"] with ID "$vmID" has NOT been found"
		fi
	fi
}

function delvm () {
	vmSearchKey=$1
	echo '' > $etc'/.active_vmlist'
	cat $etc'/active_vmlist' | grep -v $vmSearchKey >> $etc'/.active_vmlist'
	mv $etc'/.active_vmlist' $etc'/active_vmlist'
}

function addvm () {
	vmSearchKey=$1
	selectedVm=$(eval $vbm list vms | grep -i $vmSearchKey)
	selectedVmID=$(echo $selectedVm | awk '{print $2}')
	selectecVmName=$(echo $selectedVm | awk '{print $1}')
	instanceFound=$(eval $vbm list vms | grep -c $vmSearchKey)

	echo "Instances: "$instanceFound
	if [[ $instanceFound -gt 1 ]]; then
		echo "Too many instances found! Please be more specific..."
	elif [[ $instanceFound -eq 1 ]]; then
		if [[ $selectedVmID == '' ]]; then
			echo "VM '"$vmSearchKey"' is empty!"
		else
			echo -e "\tSelectedVM Param: "$vmSearchKey
			echo -e "\tSelectedVM Name: "$selectecVmName		
			echo -e "\tSelectedVM ID: "$selectedVmID

			vmIDTrimmed=$(echo $selectedVmID | sed 's/{//g' | sed 's/}//g')
			vmNameTrimmed=$(echo $selectecVmName | sed 's/"//g')

			isPresentInActiveList=$(cat $etc/active_vmlist | grep -c $vmIDTrimmed)
			#echo "isPresent: "$isPresentInActiveList

			if [[ $sec_option != "silence" ]]; then 
				if [[ $isPresentInActiveList -lt 1 ]]; then echo -e $vmIDTrimmed"\t"$vmNameTrimmed	>> $etc/active_vmlist; echo "VM '"$vmNameTrimmed"' has been added to active list!"; else echo "VM '"$vmNameTrimmed"' is already in active list!";fi
			fi 
		fi
	else
		echo "VM '"$vmSearchKey"' not found!"		
	fi
}

###################
## Main Runner ###
#################
## Switch Case #
###############
case "$1" in
    help )
		help ;;
    list )
        options='list' ;;
    power )
        options='power' ;;
    poweroff )
		options='poweroff' ;;
    addvm )
        if [[ $2 != "" ]]; then addvm $2;fi ;;
    delvm )
        if [[ $2 != "" ]]; then delvm $2;fi ;;
    stopvm )
        if [[ $2 != "" ]]; then stopvm $2;fi ;;
    startvm )
        if [[ $2 != "" ]]; then startvm $2;fi ;;
    restartvm )
        if [[ $2 != "" ]]; then restartvm $2;fi ;;
    resetvm )
        if [[ $2 != "" ]]; then resetvm $2;fi ;;
esac
sec_option=$2

## List to be active VMs
l_toBeActive_vms=$(cat $etc'/active_vmlist' | awk '{print $1}')

# avoid globbing (expansion of *).
set -f
a_toBeActive_vms=(${l_toBeActive_vms//:/ })

## List all VMs
a_list_vmName=($(eval $vbm list vms | awk '{print $1}'))
a_list_vmID=($(eval $vbm list vms | awk '{print $2}'))

if [[ $options == "poweroff" ]]; then
	powerOffAll
fi

if [[ $options == "debug" ]] || [[ $sec_option == "debug" ]]; then
	for i in "${!a_list_vmName[@]}"
	do
	    echo "$i=>${a_list_vmName[i]}"
	done

	for i in "${!a_list_vmID[@]}"
	do
	    echo "$i=>${a_list_vmID[i]}"
	done
fi

## Running VMS ID
a_running_vmID=($(eval $vbm list runningvms | awk '{print $2}'))

## Loop in all elements from list
i=0
tableDisplay="vm_name,vm_id,powered,isMeantRunning\n"

for vmID in "${a_list_vmID[@]}"
do
   :
    isVMPowered=0
	isMeantRunning=0
   	vmName=$(echo ${a_list_vmName[i]})

	vmIDTrimmed=$(echo $vmID | sed 's/{//g' | sed 's/}//g')
	isFoundInActiveVMList=$(grep -c "$vmIDTrimmed" $etc'/active_vmlist')

	if [[ $sec_option == "debug" ]]; then echo "VM "$vmName", id: "$vmIDTrimmed" isFound: "$isFoundInActiveVMList; fi

	if [[ $isFoundInActiveVMList -gt 0 ]] ; then
		isMeantRunning=1

		if [[ $sec_option != "silence" ]]; then 
			logger "Setting VM "$vmName" to meantToBeRunning=True"
		fi
	fi

	for runningvmID in "${a_running_vmID[@]}"
	do
		:
		if [[ $runningvmID == $vmID ]]; then
			#echo "Match! "$vmName" is running!"
			#VM is running - Nothing to check.
			#echo ">>> Let Me Check... runVmId: "$runningvmID", vmID: "$vmID
			isVMPowered=1
#		else
#			#VM is not running and we need to start it if we find it into the file
#			associatedVMName=$(grep "$vmIDTrimmed" $etc'/active_vmlist' | awk '{print $2}')
#			if [[ $isMeantRunning -eq 1 ]]; then
#			    echo "VM ["$associatedVMName"] with ID "$vmID" has been found and should be running"
#
#			    # Start VM process
#			    eval $vbm startvm $vmIDTrimmed --type headless
#			else
#			    echo "VM ["$associatedVMName"] with ID "$vmID" has NOT been found"
#			fi
#		else
#			vmIDTrimmed=$vmID
		fi
	done

	RED='\033[0;31m'
	GRE='\033[0;32m'
	NC='\033[0m' # No Color

	vmIDTrimmed=$(echo $vmID | sed 's/{//g' | sed 's/}//g')
	if [[ $isVMPowered -eq 1 ]]; then isVMPowered_dsp='True'; else isVMPowered_dsp='False';fi
	if [[ $isMeantRunning -eq 1 ]]; then isMeantRunning_dsp='True'; else isMeantRunning_dsp='False';fi
	if [[ $isVMPowered -eq 0 ]] && [[ $isMeantRunning -eq 1 ]]; then if [[ $options == 'power' ]]; then meantRunning_startvm; else  logger "Notify: No VM was powered, power option was off." ;fi; logger "No Need to start that VM";fi

	tableDisplay+=$(echo $vmName,$vmIDTrimmed,$isVMPowered_dsp,$isMeantRunning_dsp\\n)
	#echo 'param='$param
  	#echo $vmID" | "$vmName" | "$isVMPowered
	#echo $vmID
	((i=i+1))
done

if [[ $sec_option != "silence" ]]; then $srp'/printTable.sh' $tableDisplay; else $srp'/printTable.sh' $tableDisplay >> $srp'/logs/vmManager.log';fi 


