#!/bin/bash

N='\033[0m'
G='\033[0;32m'
Y='\033[1;33m'
R='\033[0;31m'
SYM='\xe2\x97\x8f'
SUCCESS='\xe2\x9c\x85'
FAIL='\xe2\x9d\x8c'
COMMAND=$1
LIBVIRTD_STATE=$(systemctl is-active libvirtd.socket)
CONTAINER_STATE=$(systemctl is-active kvm-server-container.service)

if [ "$EUID" != 0 ]; then
   sudo -S "$0" "$@"
   exit $?
fi

show_help() {
   cat <<EOF

   Usage: kvm-server-manage <command>

   Commands:
      enable:  Disables and stops monolithic libvirtd service if present
               Starts the KVM server container only if it isn't already running
               Enables and (re)starts the modular libvirt services
   
      restart: Performs the same actions as 'enable' but will also restart 
                  the KVM server container if active
               Warning: Running VMs will be stopped before the container is restarted
      
      disable: Disables and stops the modular libvirt daemons
               Disables and stops the KVM server container
      
      stop:    Stops the KVM Container
               Will be started again on next host boot unless 'disable' is called
      
      verify:  Prints whether the KVM server container and all required services are currently active
               Otherwise, prints inactive services that need to be addressed
      
      help:    Prints this help message

EOF
}

if [[ "$COMMAND" = "enable" || "$COMMAND" = "restart" ]]; then
   # Disable the libvirtd monolithic daemon if present
   if [ "$LIBVIRTD_STATE" = "active" ]; then
      systemctl stop libvirtd.service && \
         echo -e "${G}${SYM} ${N}Stopped libvirtd.service" || \
         echo -e "${R}${SYM} ${N}Failed to stop libvirtd.service"
      systemctl stop libvirtd{,-ro,-admin,-tcp,-tls}.socket
      systemctl disable libvirtd.service
      systemctl disable libvirtd{,-ro,-admin,-tcp,-tls}.socket
   fi

   # (Re)Start the kvm server container
   if [[ "$CONTAINER_STATE" = "inactive" || "$COMMAND" = "restart" ]]; then
      echo -e "${Y}${SYM} ${N}Starting KVM Container"
      systemctl daemon-reload
      systemctl enable kvm-server-container.service
      systemctl restart kvm-server-container.service && \
         echo -e "${G}${SYM} ${N}KVM Container Started" || \
         echo -e "${R}${SYM} ${N}KVM Container Failed to Start"
   fi

   # Enable modular libvirt daemons on the host
   for drv in qemu network nodedev nwfilter proxy secret storage
   do
      systemctl unmask container-virt${drv}d.service
      systemctl unmask virt${drv}d{,-ro,-admin}.socket
      systemctl enable container-virt${drv}d.service
      systemctl enable virt${drv}d{,-ro,-admin}.socket
      systemctl restart virt${drv}d{,-ro,-admin}.socket
      systemctl restart container-virt${drv}d.service && \
         echo -e "${G}${SYM} ${N}Started container-virt${drv}d.service" || \
         echo -e "${R}${SYM} ${N}Failed to start container-virt${drv}d.service"
   done

   for drv in log lock
   do
      systemctl enable container-virt${drv}d.service
      systemctl enable virt${drv}d{,-admin}.socket
      systemctl restart virt${drv}d{,-admin}.socket
      systemctl restart container-virt${drv}d.service && \
         echo -e "${G}${SYM} ${N}Started container-virt${drv}d.service" || \
         echo -e "${R}${SYM} ${N}Failed to start container-virt${drv}d.service"
   done

elif [[ "$CONTAINER_STATE" = "active" && ( "$COMMAND" = "stop" || "$COMMAND" = "disable" ) ]]; then
   # Disable modular libvirt daemons on the host
   if [ "$COMMAND" = "disable" ]; then
      for drv in qemu network nodedev nwfilter proxy secret storage
      do
         systemctl stop container-virt${drv}d.service && \
            echo -e "${G}${SYM} ${N}Stopped container-virt${drv}d.service" || \
            echo -e "${R}${SYM} ${N}Failed to stop container-virt${drv}d.service"
         systemctl stop virt${drv}d{,-ro,-admin}.socket
         systemctl disable container-virt${drv}d.service
         systemctl disable virt${drv}d{,-ro,-admin}.socket
      done

      for drv in log lock
      do
         systemctl stop container-virt${drv}d.service && \
            echo -e "${G}${SYM} ${N}Stopped container-virt${drv}d.service" || \
            echo -e "${R}${SYM} ${N}Failed to stop container-virt${drv}d.service"
         systemctl stop virt${drv}d{,-admin}.socket
         systemctl disable container-virt${drv}d.service
         systemctl disable virt${drv}d{,-admin}.socket
      done

      # Disable container service
      systemctl disable kvm-server-container.service
   fi

   # Stop the kvm server container. Stop the container for both "stop" and "disable"
   echo -e "${Y}${SYM} ${N}Stopping KVM Container"
   systemctl stop kvm-server-container.service && \
      echo -e "${G}${SYM} ${N}KVM Container Stopped" || \
      echo -e "${R}${SYM} ${N}KVM Container Failed to Stop"

# No-op stop and disable if the container has already been stopped. Needed for uninstall script
elif [[ "$CONTAINER_STATE" != "active" && ( "$COMMAND" = "stop" || "$COMMAND" = "disable" ) ]]; then
   echo "KVM Container already stopped. Nothing to do"

elif [ "$COMMAND" = "verify" ]; then
   # Account for libvirt services plus kvm-server-container service
   count=-1
   daemons=(qemu network nodedev nwfilter proxy secret storage log lock)

   if [ "$(systemctl is-active kvm-server-container.service)" = "active" ]; then
      let "count++"
   else
      echo -e "${R}${SYM} ${N}kvm-server-container.service is not active. See 'journalctl -xeu kvm-server-container.service' for more info"
   fi

   for drv in "${daemons[@]}"
   do
      if [ "$(systemctl is-active container-virt${drv}d.service)" = "active" ]; then
         let "count++"
      else
         echo -e "${R}${SYM} ${N}container-virt${drv}d.service is not active. See 'journalctl -xeu container-virt${drv}d.service' for more info"
      fi
   done

   if [ "${count}" -eq "${#daemons[@]}" ]; then
         echo -e "${G}${SUCCESS} ${N}All required services are currently active"
   else
         echo -e "${R}${FAIL} ${N}One or more required services are inactive"
   fi
elif [[ "$COMMAND" = "help" || "$COMMAND" = "--help" ]]; then
   show_help
else
   echo "kvm-server-manage: Unknown command \"$COMMAND\""
   show_help
fi
