#!/bin/bash

#===========================================================================================
# Copyright (C) 2017 Nafiu Shaibu.
# Purpose: Manage Virtual Machines
#-------------------------------------------------------------------------------------------
# QBox is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at your option) 
# any later version.

# QBox is distributed in the hopes 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 General
# Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#===========================================================================================

: ${LIB_DIR:=/usr/local/bin/QBox/include_dir}

echo -ne "\033]0;QBox Easy VM Manager \007"

. ${LIB_DIR}/define_macros

. ${LIB_DIR}/import '<init.h>'
. ${LIB_DIR}/import '<qdb_database.h>'
. ${LIB_DIR}/import '<boot_vm.h>'
. ${LIB_DIR}/import '<notify.h>'
. ${LIB_DIR}/import '<http_server.h>'

if NOT_DEFINE ${LOGGS_H} || NOT_DEFINE ${BASIC_UTILS_H}; then
	. ${LIB_DIR}/include '<loggs.h>'
	. ${LIB_DIR}/include '<basic_utils.h>'
fi 

##add path to .profile file
check=`cat $HOME/.profile | grep QBox`
if [ "$check" = "" ]; then
	echo -e "\n##QBox path \n[ -d /usr/local/bin/QBox ] && PATH=/usr/local/bin/QBox:\${PATH}">>${HOME}/.profile
fi

##Setting up colors
BOLD="tput bold"
RESET="tput sgr0"

_resolving_inconsistencises_qdb

case $1 in 
	
	-[Rr]|--[Rr][Uu][Nn])
		_clear_pid_qdb_event
					
		declare -a QDB_ARR=( $(init_database_qdb ${PID_DB}) )
							
		if [[ ${#QDB_ARR[*]} -eq 0 ]]; then 
			tput setaf 9
			printf "%s\n" "No Virtual is running..."
			tput sgr0
		else 
			echo -e "\nRunning Virtual Machines..."
							
			for (( index=0; index<${#QDB_ARR[*]}; index++)); do
				vm_info=${QDB_ARR[$index]//\"/}
				echo "  $(( index+1 )).       $(return_first_field ${vm_info})"
			done 	
		fi
	;;
	
	-[Kk]|--[Kk][Ii][Ll][Ll]) 
		_clear_pid_qdb_event 
					
		declare -a QDB_ARR=( $(init_database_qdb ${PID_DB}) )
							
		if [[ ${#QDB_ARR[*]} -eq 0 ]]; then 
			tput setaf 9
			printf "%s\n" "No Virtual is running..."
			tput sgr0
		else 
					
		[ "$2" != "" ] && {
				name=$(String_to_Upper $2) 
				let sizeof_arr=${#QDB_ARR[@]}
							
				QDB_ARR[$sizeof_arr]=${name}
				QDB_ARR=( $(search_val_qdb ${QDB_ARR[@]}) )
				let sizeof_arr=${#QDB_ARR[@]}
				vm_info_index=${QDB_ARR[$(( --sizeof_arr ))]} && unset 'QDB_ARR[$sizeof_arr]'
							
				[ ${vm_info_index} -ne ${ARR_IS_EMPTY} ] && [ ${vm_info_index} -ne ${SRCH_VAL_NOT_IN_ARR} ] && {
					pid_t=$(return_second_field ${QDB_ARR[$vm_info_index]})
							
					pid_t=${pid_t//\"/}
					kill -9 ${pid_t} 2>/dev/null && {
					show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "$(return_first_field ${QDB_ARR[$vm_info_index]})" \
					"$(get_string_by_name STRING_STOPPED_VM)"
				}
			}
		}
	fi
	;;
	
	-[Cc]|[Cc]|--[Cc][Oo][Pp][Yy][Rr][Ii][Gg][Hh][Tt]|[Cc][Oo][Pp][Yy][Rr][Ii][Gg][Hh][Tt])
		echo -e "QBox Easy VM Manager Copyleft (\u0254) 2017 nafiu shaibu\nQEMU is a trademark of fabrice bellard\n"
		printf "%s\n" "QBox comes with ABSOLUTELY NO WARRANTY." \
			"You may redistribute copies of this program" \
			"under the terms of the GNU General Public License." \
			"For more information about these matters, see the file named COPYING." && echo
	;;
	
	uninstall) 
    
    function uninstall_qbox() {
  		let "_test=0, _dtest=0"
	  	tmdir=${PWD}
		
		  [ -d /usr/local/bin/QBox ] && {
			  echo -e "[$$]Removing QBox...\n"
			  cd /usr/local/bin
			  sudo rm -r QBox 2>&1 1>/dev/null && _test=1
			  cd $tmdir
		  }
	
		  [ -f /usr/share/applications/QBox.desktop ] && {
			  cd /usr/share/applications 
			  sudo rm -f QBox.desktop 2>&1 1>/dev/null && _dtest=1
			  cd $tmdir
		  }
		
		  echo -e $(get_string_by_name STRING_DEEP_REMOVE "[y/[N]]")
		  read
		
		  case "$(String_to_Upper ${REPLY})" in 
			  Y|YES) 
				  cd $HOME
				  sudo rm -r .img_qemubox 2>&1 1>/dev/null
				  cd $tmdir
			  ;;
			
			  *) ;;
		  esac
		
		  if [ $_test -eq 0 ] || [ $_dtest -eq 0 ]; then
			  tput setaf 9
			  echo -e "QBox not removed."
			  tput sgr0
		  else
			  printf "%s\n" "QBox removed"
			  sudo update-desktop-database "/usr/share/applications/"
		  fi
    }

    uninstall_qbox  
	;;
	
	-s|--[Ss][Tt][Aa][Rr][Tt][Vv][Mm]) 
		name=$(String_to_Upper $2)
		
		startvm ${name} && { show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "$name" "$(get_string_by_name STRING_FOR_FULLSCRN_NOTIFICATION)"; }
	;;
	
	-l|--[Ll][Ii][Ss][Tt][Vv][Mm]) 
		declare -a QDB_ARR=( $(init_database_qdb ${VMS_DB}) )
					
		[ ${#QDB_ARR[*]} -eq 0 ] && { printf "\n\t%s\n" "No Virtual Machine created yet..."; } || {
			for (( index=0; index<${#QDB_ARR[*]}; index++)); do
				vm_info=${QDB_ARR[$index]//\"/}
				echo " $(return_first_field ${vm_info})"
			done 
		}
	;;
	
	-d|--[Dd][Ee][Ll][Ee][Tt][Ee][Vv][Mm]) 
		name=$(String_to_Upper $2)
		
		[ "$name" != "" ] && { 
			let sizeof_arr=${#QDB_ARR[@]}
			QDB_ARR[$sizeof_arr]=${name}
							
			QDB_ARR=( $(search_val_qdb ${QDB_ARR[@]}) )
			let sizeof_arr=${#QDB_ARR[@]}
			vm_info_index=${QDB_ARR[$(( --sizeof_arr ))]}
							
			[ ${vm_info_index} -ne ${ARR_IS_EMPTY} ] && [ ${vm_info_index} -ne ${SRCH_VAL_NOT_IN_ARR} ] && {
				(( sizeof_arr++ ))
				vm_info=${QDB_ARR[${vm_info_index}]}
								
				QDB_ARR[$(( sizeof_arr++ ))]=${vm_info}
				QDB_ARR[$(( sizeof_arr ))]=${VMS_DB}
								
				QDB_ARR=( $(delete_val_qdb ${QDB_ARR[@]}) ) && {
					show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "${vm_info%%|*}" \
					"$(get_string_by_name STRINGS_DELETE_VM ${vm_info%%|*})"
				}
			}
		}
	;;
	
	-[Hh]|--[Hh][Ee][Ll][Pp])
		printf "%s\n" "usage:QBox [Option]"
		
		printf "%s\n" "Options:		long Options" \
				"    -c,-C		--copyright, --COPYRIGHT" \
				"    -h,-H		--help,--HELP" \
				"     -s 		--startvm --STARTVM" \
				"     -l 		--listvm --LISTVM" \
				"     -d 		--deletevm --DELETEVM" \
				"     -r 		List running virtual Machines --run/--RUN" \
				"     -k 		Kill running virtual Machines --kill/--KILL" \
				"     uninstall 		Uninstall QBox" \
				"     nocheck 		Do not check for packages" && echo
				
		printf "%s\n" "Modes:                Definitions" \
				"    --dialog          Start QBox in curses dialog Mode.Is the default mode." \
				"    --cli,-i          Start QBox in commandline text menu mode." \
				"    --web,-w          Start QBox in web interface mode."
		
		printf "%s\n" "Contact me @ <github.com/nshaibu>" && echo 
		printf "%s\n" "QBox help users create and manage virtual machines locally and remotely" 
		printf "%s\n" "To run this program on microsoft windows, install cygwin and Xserver." \
			"The program might not work very well on other shells like ksh, csh, tcsh. You" \
			"can make the neccesary changes to the code by reading the README file or use" \
			"sh/bash shell" && echo
	;;

	--[Ww][Ee][Bb]|-w)
		
		if server_is_not_running ; then
			let "i=0, pid_t=-1"
									
			tm_t=$(date +%T)
			pid_host_ip=$(httpd_start)
									
			pid_t=${pid_host_ip%%|*}
			host_ip_t=${pid_host_ip##*|}
			
			declare -a msg_arr=("[${pid_t}]using_host_ip:${host_ip_t}" "[${pid_t}]starting_httpd..." \
							"[${pid_t}]httpd_started_at_${tm_t}" "[${pid_t}]httpd_listening_on_port_4020" \
							"[${pid_t}]starting_QBox_server..." "[${pid_t}]QBox_server_on_port_4040" \
							"[${pid_t}]getting_qbox_server_pid" "[$pid_t]QBox_server_started_at_$(date +%T)" \
							"[${pid_t}]trying_to_open_browser" "[${pid_t}]Access:http://${host_ip_t}:4020" )
								
			[ ${pid_t} -ne -1  ] && {
				for (( index=0; index<${#msg_arr[@]}; index++ )); do 
					echo -e "${msg_arr[$index]//_/ }"
					sleep 0.6
						
					[ $index -eq 4 ] && { qbox_server_start; }
					[ $index -eq 6 ] && {
						pid_QS=$(get_qboxServer_pid)
						
						if [[ -n ${pid_QS} ]]; then
							[ $pid_QS -gt ${PID_MAX} ] && { echo "qbox server could not start"; kill -9 ${pid_t} 2>/dev/null; exit 1; } 
						fi 
					}
					
					[ $index -eq 8 ] && {
						if [ "${host_ip_t}" = "127.0.0.1" ] || [ "${host_ip_t}" = "localhost" ]; then
							browser=$(which xdg-open || which gnome-open ) && {
								: #${browser} "http://localhost:4020/www" 2>&1 1>/dev/null
							}
						fi
					}
						
					[ $index -eq 9 ] && { 
						echo "${pid_t}|${tm_t}|http://${host_ip_t}:4020">${test_serv_running}
						
						#pressing any key to exit
						tput bold
						echo -en "[${pid_t}]Hit any key to exit..."
						tput sgr0
						read
						
						server_stop $(return_first_field ${test_serv_running}) && { rm -f ${test_serv_running} 2>/dev/null; } 
						stop_qbox_server 2>&1 1>/dev/null && {
							show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "${pid_t}" \
							"$(get_string_by_name STRING_STOP_QBOX_REMOTE_MANAGER)"
						}
					}
				done 
			}
		else 
			pid_t=$(return_first_field ${test_serv_running})	
			tm_t=$(return_second_field ${test_serv_running})
			url=$(return_n_field ${test_serv_running} 3 "|")
			pid_QS=$(get_qboxServer_pid)
			
			printf "Server already started at ${tm_t} with pid of ${pid_t} on url ${url} \n"
			echo -n "Do you want to stop the server?[y/[N]] "
			read -n 1

			case ${REPLY} in 
				[Yy]) 
					server_stop ${pid_t} && { rm -f ${test_serv_running} 2>/dev/null; } 
					server_stop ${pid_QS} && { rm -f ${qbox_server_running} 2>/dev/null; }
				;;
				*) ;;
			esac
			echo 
		fi
								 						
	;;
	
	--[Cc][Ll][Ii]|-[Ii])
	
		##check for packages 
		if [[ "$2" != "nocheck" ]]; then
			. ${BASIC_BASH}/check_pkg_install.sh %CHECK_START%
		fi 
	
		show_notification low ${QBOX_DIR}/icon/QBox.png "QBox" "The Easy VM Manager" 
		. ${BASIC_BASH}/qemu-ansi-art.sh
		
		function other_options_menu(){
			clear
			tput bold
			echo -e "\t\t\tOther Options\n"
			tput sgr0
			echo -e "\t1. Information On Virtual Machines"
			echo -e "\t2. Create Shortcut"
			echo -e "\t3. QBox Logs"
			echo -e "\t0. Back \u2b05 \n\n"
	
			echo -en "\t\tEnter Option: "
			read -n 1 opt
		}	
	
	
		function qemu_menu_func(){
			clear
			#move_center 40 10
			echo
			echo -e "\t\t\t\t `${BOLD}` QBox Menu `${RESET}`\n"
			echo -e "\t1. Boot Created Virtual Machine"
			echo -e "\t2. Create New Virtual Machine"
			echo -e "\t3. Delete Virtual Machine"
			echo -e "\t4. Other Options"
			echo -e "\t5. Reconfigure Virtual Machine"
			echo -e "\t6. Stop Running Virtual Machine"
			echo -e "\t7. QBox Remote Manager"
			echo -e "\t8. Direct Linux Boot"
			echo -e "\t0. Exit `tput setaf 9` \U274C \n\n"
			tput sgr0
		
			echo -en "\t\tEnter Option: "
			read -n 1 option
		}


		while true; do
			clear
			qemu_menu_func
	
			case $option in
				0) break;;
				1) 
					declare -a QDB_ARR=( $(init_database_qdb ${VMS_DB}) )
					
					if [[ ${#QDB_ARR[*]} -eq 0 ]]; then 
						tput setaf 9
						printf "\n\t%s\n" "No Virtual Machine created yet..."
						tput sgr0
					else 
						echo -e "\n\nselect a vm"
						
						for (( index=0; index<${#QDB_ARR[*]}; index++)); do
							vm_info=${QDB_ARR[$index]//\"/}
							echo "  $(( index+1 )).       $(return_first_field ${vm_info})"
						done 
						
						printf "\n%s" "Enter the name of the VM to boot[ENTER] "
						read name
						
						if [[ ${name} != "" ]]; then
							name=$(String_to_Upper ${name}) 
							
							startvm ${name} && {
								show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "$name" \
								"$(get_string_by_name STRING_FOR_FULLSCRN_NOTIFICATION)"
							}
						fi
					fi 
			;;
				2) . ${BASIC_BASH}/qemu-im-box.sh ;;
				3) 
					declare -a QDB_ARR=( $(init_database_qdb ${VMS_DB}) )
							
					if [[ ${#QDB_ARR[*]} -eq 0 ]]; then 
						tput setaf 9
						printf "\n\t%s\n" "No Virtual Machine created yet..."
						tput sgr0
					else 
						echo -e "\n\nselect a vm"
							
						for (( index=0; index<${#QDB_ARR[*]}; index++)); do
							vm_info=${QDB_ARR[$index]//\"/}
							echo "  $(( index+1 )).       $(return_first_field ${vm_info})"
						done 					
						
						echo
						printf "%s" "Enter the name of the VM to delete[ENTER] "
						read name
				
						[ "$name" != "" ] && { 
							name=$(String_to_Upper $name)
							let sizeof_arr=${#QDB_ARR[@]}
							QDB_ARR[$sizeof_arr]=${name}
							
							QDB_ARR=( $(search_val_qdb ${QDB_ARR[@]}) )
							let sizeof_arr=${#QDB_ARR[@]}
							vm_info_index=${QDB_ARR[$(( --sizeof_arr ))]}
							
							[ ${vm_info_index} -ne ${ARR_IS_EMPTY} ] && [ ${vm_info_index} -ne ${SRCH_VAL_NOT_IN_ARR} ] && {
								(( sizeof_arr++ ))
								vm_info=${QDB_ARR[${vm_info_index}]}
								
								QDB_ARR[$(( sizeof_arr++ ))]=${vm_info}
								QDB_ARR[$(( sizeof_arr ))]=${VMS_DB}
								
								QDB_ARR=( $(delete_val_qdb ${QDB_ARR[@]}) ) && {
									show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "${vm_info%%|*}" \
									"$(get_string_by_name STRINGS_DELETE_VM ${vm_info%%|*})"
								}
							}
						}
					fi 
			;;
				4) 
				
					while true ; do 
						clear 
						other_options_menu
					
						case $opt in
						0) break ;;
						1) 
							declare -a QDB_ARR=( $(init_database_qdb ${VMS_DB}) )
							
							if [[ ${#QDB_ARR[*]} -eq 0 ]]; then 
								tput setaf 9
								printf "\n\t%s\n" "No Virtual Machine created yet..."
								tput sgr0
							else 
								echo -e "\n\nselect a vm"
							
								for (( index=0; index<${#QDB_ARR[*]}; index++)); do
									vm_info=${QDB_ARR[$index]//\"/}
									echo "  $(( index+1 )).       $(return_first_field ${vm_info})"
								done 						
								
								echo
								read -p "Choose a VM[ENTER] " name
								
								[ "$name" != "" ] && {
									let sizeof_arr=${#QDB_ARR[@]}
									name=$(String_to_Upper $name)
									QDB_ARR[$sizeof_arr]=${name}
									
									QDB_ARR=( $(search_val_qdb ${QDB_ARR[@]}) )
									let sizeof_arr=${#QDB_ARR[@]}
									let vm_info_index=${QDB_ARR[$(( --sizeof_arr ))]} && unset 'QDB_ARR[$sizeof_arr]'
									
									[ ${vm_info_index} -ne ${ARR_IS_EMPTY} ] && [ ${vm_info_index} -ne ${SRCH_VAL_NOT_IN_ARR} ] && {
										boot_file_name=${QDB_ARR[$vm_info_index]//\"/}
										boot_file_name=$(return_second_field ${boot_file_name})
										
										clear
										bash ${BASIC_BASH}/qbox_display_vm_info.sh "${BOOT_DIR}/${boot_file_name}"
									}
								} 						
							fi 
						;;
						2) . ${BASIC_BASH}/create_desktop_file.sh ;;
						3) . ${BASIC_BASH}/qboxlogs.sh ;;
						*) 
							clear
							echo "wrong Option"		
						 ;;
						esac
						
						echo -en "\n\n\t\t\tHit any key to continue"
						read -n 1 line
						
					done
				
				;;
				5) . ${BASIC_BASH}/qemu-reconfigure.sh ;;
				6) 
					_clear_pid_qdb_event
					echo
					
					declare -a QDB_ARR=( $(init_database_qdb ${PID_DB}) )
							
					if [[ ${#QDB_ARR[*]} -eq 0 ]]; then 
						tput setaf 9
						printf "\n\t%s\n" "No Virtual is running..."
						tput sgr0
					else 
						echo -e "\n\nRunning Virtual Machines..."
							
						for (( index=0; index<${#QDB_ARR[*]}; index++)); do
								vm_info=${QDB_ARR[$index]//\"/}
								echo "  $(( index+1 )).       $(return_first_field ${vm_info})"
						done 						
								
						echo
						read -p "Enter the name of VM to stop[ENTER] " vmn
					
						[ "$vmn" != "" ] && {
							name=$(String_to_Upper ${vmn}) 
							let sizeof_arr=${#QDB_ARR[@]}
							
							QDB_ARR[$sizeof_arr]=${name}
							QDB_ARR=( $(search_val_qdb ${QDB_ARR[@]}) )
							let sizeof_arr=${#QDB_ARR[@]}
							vm_info_index=${QDB_ARR[$(( --sizeof_arr ))]} && unset 'QDB_ARR[$sizeof_arr]'
							
							[ ${vm_info_index} -ne ${ARR_IS_EMPTY} ] && [ ${vm_info_index} -ne ${SRCH_VAL_NOT_IN_ARR} ] && {
								pid_t=$(return_second_field ${QDB_ARR[$vm_info_index]})
								
								pid_t=${pid_t//\"/}
								kill -9 ${pid_t} 2>/dev/null && {
									show_notification low ${QBOX_DIR}/icon/qbox_shortcut.png "$(return_first_field ${QDB_ARR[$vm_info_index]})" \
									"$(get_string_by_name STRING_STOPPED_VM)"
								}
							}
						}
					fi
			;;
				7) : ;;
				8) . ${BASIC_BASH}/direct_linux_boot.sh ;;
				*)
					clear
					echo "wrong Option";;
			esac
		
			echo -en "\n\n\t\t\tHit any key to continue"
			read -n 1 line
		done
		clear
	;;
	*) 
		[ "$1" != "nocheck" ] && {
			. ${BASIC_BASH}/check_pkg_install.sh %CHECK_START%
		} 
		
		. ${QBOX_DIR}/dialog_ui/qbox_main_menu.sh
		clear
	;;
esac

exit 0
