#!/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:
#   --config                    - Read the specified configuration file.
#   --start-daemon              - starts the daemon running.
#   --stop-daemon               - stops the daemon running.
#   --activate-window-picker    - tells the daemon to show the window picker.
#   --deactivate-window-picker  - tells the daemon to hide the window picker.
#   --toggle-window-picker      - tells the daemon to toggle the window picker.
#   --prev                      - launch initially focussed to previous selection.
#   --next                      - launch initially focussed to next selection.
#   --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)                                   shift && _config="$1" ;;
      --start-daemon|--start)                     _start_daemon=true ;;
      --stop-daemon|--stop)                       _stop_daemon=true ;;
      --activate-window-picker|--activate)        _activate=true ;;
      --deactivate-window-picker|--deactivate)    _deactivate=true ;;
      --toggle-window-picker|--toggle)            _toggle=true ;;
      --prev)                                     _prev=true ;;
      --next)                                     _next=true ;;
      --help|-h)                                  _help=true ;;
      -S)                                         _sync=true ;;

    esac

    shift
  done

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

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

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

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

_main()
{
  lastActivationTimeoutSeconds=1

  psSkippyActivateOut="`pgrep -f 'skippy-xd --activate'`"
  psSkippyDeactivateOut="`pgrep -f 'skippy-xd --deactivate'`"
  psSkippyToggleOut="`pgrep -f 'skippy-xd --toggle'`"

  _other_clients=0
  for pid in $psSkippyActivateOut $psSkippyDeactivateOut $psSkippyToggleOut; 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 "$@"
)
