# Error codes:
#    0  Process is not running
#    1  Wrong argument
#  128  Process is running

run_code=128
# default timeout in seconds
stop_timeout=20

print_usage() {
  echo "Usage:"
  echo "        ./process_state.sh <process name>"
  echo "               Checks whether the process with <process name> is running."
  echo "               Returns $run_code if running, 0 otherwise."
  echo "        ./process_state.sh <process name> <command> [<command>...] [<timeout>]"
  echo "               Stops the process with <process name>."
  echo "               <command> is either stop or abort or kill."
  echo "               Timeout is the maximum wait time in seconds in case process cannot be stopped."
  echo "               Example: ./process_state.sh knxstack stop abort kill 100"
}

number_of_args=0

count_args() {
  number_of_args=0
  for arg in $@
  do
    number_of_args=$(( $number_of_args + 1 ))
  done
}

is_process_running() {
  local result=
  if [ "`$SHELL --help 2>&1 | grep -Ee '-pc-'`" == "" ]
  then  
    # device command
    result=`ps | awk '{{print $3}}' | grep -Ee '^(.*[/])?'$1'$'`
  else
    # ubuntu command
    result=`ps | awk '{{print $4}}' | grep -Ee '^(.*[/])?'$1'$'`
  fi
  if [ "$result" != "" ]
  then
    return $run_code
  fi
  return 0
}

show_is_process_running() {
  is_process_running $1
  local result=$?
  if [ $result -eq $run_code ]
  then
    echo Process "'"$1"'" is running.
  else
    echo Process "'"$1"'" is NOT running.
  fi
  return $result
}

evaluate_arguments() {
  #declare -i i
  local param=
  local number=0
  local i=0
  for param in $@
  do
    i=$(( $i + 1 ))
    if [ $i -gt 1 ]
    then
      number=$(($param))
      if [ $i -eq $number_of_args -a "$param" == "$number" ]
      then
        stop_timeout=$param
        echo "Timeout: ${stop_timeout} seconds"
      else
        if [ "$param" == "stop" -o "$param" == "abort" -o "$param" == "kill" ]
        then
          if [ "$commands" != "" ]; then commands="$commands "; fi
          commands="$commands$param"
        else
          print_usage
          return 1
        fi
      fi
    fi
  done
  return 0
}

stop_process() {
  evaluate_arguments $@
  local process=$1
  local result=$?
  if [ $result -ne 0 ]; then exit $result; fi
  
  is_process_running $process
  local running=$?
  if [ $running -eq 0 ]
  then
    echo "Process '$process' is not running."
    return 0
  fi
  local total_expired=0
  for command in $commands
  do
    is_process_running $process
    running=$?
    if [ $running -ne 0 ]
    then
      local expired=0;
      local signal=
      if [ "$command" == "abort" ]; then signal="-s 6"; fi
      if [ "$command" == "kill" ]; then signal="-s 9"; fi
      local command_line="killall $signal $process"
      echo $command_line
      $command_line
      while [ $running -ne 0 -a $expired -lt $stop_timeout ]
      do
        sleep 1
        expired=$(( $expired + 1 ))
        total_expired=$(( $total_expired + 1 ))
        echo -n .
        is_process_running $process
        running=$?
      done
      if [ $running -ne 0 ]
      then
        echo "timeout"
      else
        echo
        echo "Process '$process' stopped within $total_expired seconds."
      fi
    fi
  done
  if [ $running -ne 0 ]
  then
    echo "Process '$process' is still running after $total_expired seconds."
  fi
  return $running
}

commands=
count_args $@

if [ $number_of_args -eq 1 ]
then
  show_is_process_running $1
else
  if [ $number_of_args -gt 1 ]
  then
    stop_process $@
  fi
fi

