#!/bin/bash

process_killer_helper() {
   if [ "$(type -t error_handler)" = "function" ]; then
      ## Error handler already implemented. Using it.
      trap "error_handler" ERR
   else
      ## No error available yet. Implementing one.
      error_handler() {
         echo "Error detected! BASH_COMMAND: $BASH_COMMAND | exit_code: $exit_code"
      }
   fi

   if [ "$lastpid" = "" ]; then
      return 0
   fi

   ## Can not use `kill`, must use `ps`, because kill will always return a
   ## a non-zero exit code if the process is owned by a different user.
   local ps_p_exit_code
   ps_p_exit_code="0"
   ps -p "$lastpid" >/dev/null 2>/dev/null || { ps_p_exit_code="$?" ; true; };

   if [ ! "$ps_p_exit_code" = "0" ]; then
      return 0
   fi

   ## >/dev/null 2>/dev/null to prevent seeing error due to race conditions (process in meanwhile already terminated).
   kill -s sigterm "$lastpid" >/dev/null 2>/dev/null || true

   local i
   i="0"

   ## Give remaining processes up to 5 seconds after sending signal sigterm (above) before killing them sending signal sigkill.
   while true; do
      local ps_p_exit_code
      ps_p_exit_code="0"
      ps -p "$lastpid" >/dev/null 2>/dev/null || { ps_p_exit_code="$?" ; true; };

      if [ ! "$ps_p_exit_code" = "0" ]; then
         ## ps_p_exit_code is not 0, process no longer running. That's it.
         return 0
      fi
      ## Process still running.

      ## Wait up to 5 seconds for the process to terminate.
      i="$(( $i + 1 ))"
      if [ "$i" -lt "5" ]; then
         light_sleep 1
         continue
      fi
      break
   done

   ## Seems like process still running. Terminating using sigkill.
   kill -s sigkill "$lastpid" >/dev/null 2>/dev/null || true

   return 0
}
