#!/bin/bash

usage()
{
  echo
  echo "Usage: $PROG_NAME [-n:VM_NAME] "
  echo
  echo " -n      =   Name of the virtual machine to stop."
  echo
  exit 0
}

function get_vm_state(){ 
  echo "$PROG_NAME: Getting $VM_NAME current state ..."
  state="$(virsh dominfo "$1" | grep -w "State:" | awk '{print $2}')"
}

set_variable()
{
  local varname=$1
  shift
  if [ -z "${!varname}" ]; then
    eval "$varname=\"$@\""
  else
    echo "Error: $varname already set"
    usage
  fi
}

####################################################################
# Main script starts here

set_variable VM_STATE ""
set_variable PROG_NAME "$(basename "$0")"
set_variable CHECK_FILE "/tmp/VM_PREV_STATE"

if [[ $1 == "" ]]; then
    usage;
    exit;
else
    while getopts 'n:?h' c
    do
    case $c in
        n) set_variable VM_NAME "$OPTARG" ;;
        h|?) usage ;; esac
    done
fi



i=0
# I put a variable in my scripts named PROG_NAME which
# holds the name of the program being run.  You can get this
# value from the first item on the command line ($0).


# ---------------
# Error Handling
# ---------------
# set -e
# trap 'catch $? $LINENO' EXIT

# catch() {
#   echo "catching!"
#   if [ "$1" != "0" ]; then
#     # error handling goes here
#     echo "Error $1 occurred on $2 in $PROG_NAME"
#   fi
# }


rm "$CHECK_FILE" 


# ---------------
# VM Not Running
# ---------------
get_vm_state "$VM_NAME"
echo "$state" > "$CHECK_FILE"
if [ "$state" != "running" ]
then
  echo "$PROG_NAME: $VM_NAME not running" >&2
  exit 0
else
  virsh shutdown "$VM_NAME"
fi

# ---------------
# Clean stop VM
# ---------------
get_vm_state "$VM_NAME"
while [ "$state" == "running" ]
do
  ((i++))
  if [[ "$i" == '30' ]]; then
    break
  fi  
  sleep 10
  get_vm_state "$VM_NAME"
done;

# ---------------
# Force stop VM
# ---------------
get_vm_state "$VM_NAME"
if [ "$state" == "running" ]
then
  i=0
  echo "$PROG_NAME: $VM_NAME force shutdown initiated" >&2
  virsh destroy "$VM_NAME"
  get_vm_state "$VM_NAME"
  while [ "$state" == "running" ]
  do
    ((i++))
    if [[ "$i" == '30' ]] 
    then
      break
    fi  
    sleep 10
    get_vm_state "$VM_NAME"
  done;
else
  echo "$PROG_NAME: Successfully stopped $VM_NAME after $i x 10 sec attempts"
  exit 0
fi

# -----------------
# Unable to stop VM
# -----------------
get_vm_state "$VM_NAME"
if [ "$state" == "running" ]
then
  echo "$PROG_NAME: Could not stop $VM_NAME" >&2
  exit 1
else
  echo "$PROG_NAME: Forcelly stopped $VM_NAME after $i x 10 sec attempts">&2
  exit 0
fi

