#!/bin/sh
#
# skippy-xd-runner
#
# A wrapper script to deal with too many requests / locks up skippy
# When skippy is bound to a global keybinding, and held keys repeat
#
# Functions:
#   * Restart skippy daemon if stuck / unresponsive (> 1 sec)
#   * Don't overload skippy with any simultaneous requests
#   * Auto-start daemon for --activate and --toggle commands
#
# Usage:
#
#   skippy-xd-runner <args>
#
# The available commands are:
#  [no command]        - activate expose once without daemon.
#  --config-reload     - reload configuration file; currently the file path must remain unchanged.
#  --config            - read the specified configuration file.
#  --start-daemon      - starts the daemon running.
#  --stop-daemon       - stops the daemon running.
#  --activate-expose   - connects to daemon and activate expose.
#  --toggle-expose     - connects to daemon and toggle expose.
#  --activate-paging   - connects to daemon and activate paging.
#  --toggle-paging     - connects to daemon and toggle paging.
#  --deactivate        - connects to daemon and deactivate expose or paging.
#  --prev              - focus window to previous.
#  --next              - focus window to next.
#  
#  --help              - show this message.
#   -S                          - Synchronize X operation (debugging).
#
#
#

_kill_skippy() {

  killall 'skippy-xd'

  if [ -f '/tmp/skippy-xd-fifo' ]; then
    rm /tmp/skippy-xd-fifo
    touch /tmp/skippy-xd-fifo
  fi

}


_parse_args()
{
  while [ "$1" ]; do
    arg="$1"

    case $arg in

      --config-reload)                            _config_reload=true ;;
      --config)                                   shift && _config="$1" ;;
      --start-daemon|--start)                     _start_daemon=true ;;
      --stop-daemon|--stop)                       _stop_daemon=true ;;
      --activate-expose|--activate)               _activate_expose=true ;;
      --toggle-expose|--toggle)                   _toggle_expose=true ;;
      --activate-paging|--activate)               _activate_paging=true ;;
      --toggle-paging|--toggle)                   _toggle_paging=true ;;
      --deactivate|--deactivate)                  _deactivate=true ;;
      --prev)                                     _prev=true ;;
      --next)                                     _next=true ;;
      --help|-h)                                  _help=true ;;
      -S)                                         _sync=true ;;

    esac

    shift
  done

  unset _first_arg
  if [ "$_activate_expose" ]; then
    _first_arg="--activate-expose"
  fi

  if [ "$_toggle_expose" ]; then
    _first_arg="--toggle-expose"
  fi

  if [ "$_activate_paging" ]; then
    _first_arg="--activate-paging"
  fi

  if [ "$_toggle_paging" ]; then
    _first_arg="--toggle-paging"
  fi

  if [ "$_deactivate" ]; then
    _first_arg="--deactivate"
  fi

  if [ "$_first_arg" ]; then
    unset _start_daemon
  fi
}

_main()
{
  lastActivationTimeoutSeconds=1

  psSkippyActivateExposeOut="`pgrep -f 'skippy-xd --activate-expose'`"
  psSkippyToggleExposeOut="`pgrep -f 'skippy-xd --toggle-expose'`"
  psSkippyActivatePagingOut="`pgrep -f 'skippy-xd --activate-paging'`"
  psSkippyTogglePagingOut="`pgrep -f 'skippy-xd --toggle-paging'`"
  psSkippyDeactivateOut="`pgrep -f 'skippy-xd --deactivate'`"

  _other_clients=0
  for pid in $psSkippyActivateExposeOut $psSkippyToggleExposeOut $psSkippyActivatePagingOut $psSkippyTogglePagingOut $psSkippyDeactivateOut; do
    ptime="$(ps -o etimes= -p "$pid")"
    if [ "$ptime" -ge "$lastActivationTimeoutSeconds" ]; then
      _killall=true
      break
    fi
    _other_clients="$(expr $i + 1)"
  done


  if [ "$_other_clients" -gt "1" ]; then
    _killall=true
  fi

  # if a process to activate skippy already exists, with a runtime that is too long
  # (> 1sec). Then assume skippy-xd is stuck, so we must kill its all of its locked processess
  if [ "$_killall" ]; then
    _kill_skippy;

  # if the skippy-xd daemon is busy, and servicing only 1 other recent request (< 1 sec old)
  # then we assume the alt-tab key is being held down. so we must skip / omit our extra
  # requests such as this one, since too many requests will lock up the skippy daemon
  elif [ "$_first_arg" ] && [ "$_other_clients" -eq "1" ]; then
    echo "refused. skippy is still busy servicing the previous client request"
    exit 1
  fi

  # if the action requires the skippy-xd daemon, but it is not already running, we should start it
  if [ "$_first_arg" ] && [ ! "$_deactivate" ] && [ ! "$(pgrep -f 'skippy-xd ')" ]; then

    if [ "$_config" ]; then
      skippy-xd --start-daemon --config "$_config" &

    else
      skippy-xd --start-daemon &
    fi
  fi

  # pass all arguments onto skippy unmodified. but repeat $first_arg up front, to show up in pgrep -f output
  skippy-xd $_first_arg "$@"
  exit $?
}

(
  _parse_args "$@";
  _main "$@"
)
