#!/bin/bash

set -e
set -u

APPSH_HOME=$(cd $(dirname "$0")/.. && pwd)

. $APPSH_HOME/lib/common
# HEADER END

do_status() {
  if [ -z "$PID" ]
  then
    echo stopped
  else
    if [ `ps -p "$PID" 2>/dev/null | wc -l` -gt 1 ]
    then
      echo running
    else
      echo crashed
    fi
  fi
}

find_launcher() {
  launcher=`app-conf get app.launcher`

  if [ ! -z "$launcher" ]
  then
    if [ ! -r "$launcher" ]
    then
      fatal "No such file: $launcher" >&2
    fi
  else
    # Search for the launcher
    if [ -d bin ]
    then
      launcher=`grep_path ".*" bin`

      # This will happen if grep_path returns multiple files.
      # As we don't know which to choose, we'll fail.
      if [ ! -x "$launcher" ]
      then
        launcher=""
      fi
    fi
  fi

  if [[ $launcher == "" ]]
  then
    fatal "No launcher configured (app.launcher), could not find a single executable to run." >&2
  fi

  if [[ ! -x $launcher ]]
  then
    fatal "Launcher not executable: $launcher" >&2
  fi

  echo $launcher
}

command_start() {
  launcher=`find_launcher`

  case `do_status` in
    running)
      echo "The application is already running as $PID."
      exit 1
      ;;
  esac

  echo "Starting app with $launcher, pwd=`pwd`"
  $launcher <&- 1<&- 2<&- &

  PID=$!
  echo "Application launched as $PID"
  echo $PID > $pid_file

  return 0
}

command_stop() {
  case `do_status` in
    stopped)
      echo "The application not running."
      return 1
      ;;
    crashed)
      echo "The application crashed. Was running as $PID"
      # TODO: should this remove the PID file? That makes it
      # possible to run "stop" to stop "status" from showing
      # "crashed". Perhaps just a "clear" goal to clear the pid file.
      return 1
      ;;
  esac

  echo -n "Sending kill TERM to $PID, waiting for shutdown"
  kill -TERM $PID

  for i in {1..10}
  do
    if [ "`do_status`" != "running" ]
    then
      PID=
      break
    fi

    sleep 1
    echo -n .
  done

  if [[ $PID != "" ]]
  then
    echo "This is taking too long, sending KILL to $PID "
    kill -KILL $PID

    while [ "`do_status`" == "running" ]
    do
      sleep 1
      echo -n .
    done
  fi

  echo " OK"
  rm -f $pid_file
  return 0
}

command_status() {
  case `do_status` in
    running)
      echo "Running as $PID"
      ;;
    stopped)
      echo "Not running"
      ;;
    crashed)
      echo "Crashed. Was running as $PID"
      ;;
  esac
}

command_restart() {
  set +e
  command_stop
  set -e
  command_start
}

APP_HOME=${APP_HOME-}

if [[ $APP_HOME == "" ]]
then
  fatal "\$APP_HOME has to be set."
fi

pid_file=$APP_HOME/.app/pid 

PID=
if [ -r $pid_file ]
then
  PID="`cat $pid_file`"
fi

command="$1"

case "$command" in
  start|stop|status|restart)
    command_$command
    ret=$?
    exit $ret
    ;;
  *)
    fatal "Invalid command: $command"
    ;;
esac

exit $?