#!/bin/bash
# Add ' -x' above to debug
#
# Start an EDDN Service, including redirecting output to a log file.

###########################################################################
# Exit codes
###########################################################################
EXIT_CONFIG_MISSING=1
EXIT_SERVICE_BIN_MISSING=2
EXIT_CL_ARGS=3
EXIT_SERVICE_ALREADY_RUNNING=4
###########################################################################

###########################################################################
# Functions
###########################################################################
##################################################
# Print usage information
##################################################
usage() {
  echo "Usage: $(basename $0) ( live | beta | dev ) ( gateway | monitor | relay | bouncer ) [ --from-source [ --background ] ]" >&2
}
##################################################

##################################################
# Check if the given PID is running, owned by the expected user, and with
# the expected command.
#
# Returns:  0 if PID, user and command all match
#           1 if no process
#           2 if PID exists, but not as user
#           3 if PID exists, as user, but isn't the command.
##################################################
check_process() {
  PROC_PID="$1"
  PROC_USER="$2"
  PROC_CMD="$3"

  # Check if a process of the given PID even exists.
  if ! PROC_PS=$(ps --pid "${PROC_PID}" --format euser,comm --no-headers) ;
  then
    return 1
  fi

  # Check if the user matches
  PROC_PS_USER=$( echo "${PROC_PS}" | awk '{print $1;'})
  if [ "${PROC_PS_USER}" != "${PROC_USER}" ];
  then
    return 2
  fi

  # Check if the command matches
  PROC_PS_CMD=$( echo "${PROC_PS}" | awk '{print $2;'})
  if [ "${PROC_PS_CMD}" != "${PROC_CMD}" ];
  then
    return 3
  fi

  return 0
}
##################################################
###########################################################################

if [ -z "${1}" ];
then
  usage
  echo "No EDDN environment specified." >&2
  exit ${EXIT_CL_ARGS}
fi
EDDN_ENV="${1}"

if [ -z "${2}" ];
then
  usage
  echo "No EDDN service specified." >&2
  exit ${EXIT_CL_ARGS}
fi
SERVICE="${2}"
case "${SERVICE}" in
  gateway|monitor|relay|bouncer)
    ;;
  *)
    usage
    echo "Invalid EDDN service: ${SERVICE}"
    exit ${EXIT_CL_ARGS}
    ;;
esac

if [ ! -z "${3}" ];
then
  if [ "${3}" != "--from-source" ];
  then
    usage
    echo "Un-recognised argument: ${3}" >&2
    exit ${EXIT_CL_ARGS}
  fi
  FROM_SOURCE="1"
  if [ ! -z "${4}" ];
  then
    if [ "${4}" != "--background" ];
    then
      usage
      echo "Un-recognised argument: ${4}" >&2
    fi
    BACKGROUND=1
  fi
fi

EXEC_PATH=$(dirname $0)
#echo "EXEC_PATH: ${EXEC_PATH}"

# Ensure we're in the correct place
cd ${EXEC_PATH}
#pwd

# Bring in some common configuration
if [ ! -f "eddn_${EDDN_ENV}_config" ];
then
  echo "eddn_${EDDN_ENV}_config is missing from $(pwd)" >&2
  exit ${EXIT_CONFIG_MISSING}
fi
. "./eddn_${EDDN_ENV}_config"
mkdir -p "${LOG_DIR}"

# Use the python venv
. "${PYTHON_VENV}/bin/activate"

# Running from source or install ?
if [ -z "${FROM_SOURCE}" ];
then
  # From install
  if [ ! -f "${PYTHON_VENV}/bin/eddn-${SERVICE}" ];
  then
    echo "${SERVICE} is missing from ${PYTHON_VENV}/bin" >&2
    exit ${EXIT_SERVICE_BIN_MISSING}
  fi
  
  if [ -f "${LOG_DIR}/${SERVICE}.pid" ];
  then
    if check_process "$(cat ${LOG_DIR}/${SERVICE}.pid)" "${USER}" eddn-${SERVICE} ;
    then
      echo "${SERVICE}: already running as PID $(cat "${LOG_DIR}/${SERVICE}.pid")" >&2
      exit ${EXIT_SERVICE_ALREADY_RUNNING}
    fi
  fi

  ${PYTHON_VENV}/bin/eddn-${SERVICE} --config "${CONFIG_OVERRIDE}" >> "${LOG_DIR}/${SERVICE}.log" 2>&1 &
  echo $! > "${LOG_DIR}/${SERVICE}.pid"
  wait $(cat "${LOG_DIR}/${SERVICE}.pid")
else
  # From source
  cd "${SRC_DIR}/src/eddn"
  #pwd
  # For now the source file has Camel case.
  #echo ${SERVICE}
  SERVICE_CAMEL=$(echo ${SERVICE} | sed -s 's/^\(.\)/\u\1/;')
  #echo ${SERVICE_CAMEL}
  if [ -z "${BACKGROUND}" ];
  then
    echo "Starting ${SERVICE_CAMEL} in foreground..."
    ${PYTHON_VENV}/bin/python ${SERVICE_CAMEL}.py --config "${CONFIG_OVERRIDE}"
  else
    # We need to ensure there isn't already one, via the .pid file
    if [ -f "${LOG_DIR}/${SERVICE}.pid" ];
    then
      if check_process "$(cat ${LOG_DIR}/${SERVICE}.pid)" "${USER}" eddn-${SERVICE} ;
      then
        echo "${SERVICE}: already running as PID $(cat "${LOG_DIR}/${SERVICE}.pid")" >&2
        exit ${EXIT_SERVICE_ALREADY_RUNNING}
      fi
    fi

    echo "Starting ${SERVICE_CAMEL} in background..."
    ${PYTHON_VENV}/bin/python ${SERVICE_CAMEL}.py --config "${CONFIG_OVERRIDE}" >> "${LOG_DIR}/${SERVICE}.log" 2>&1 &
    PID=$!
    echo ${PID} > "${LOG_DIR}/${SERVICE}.pid"
    echo "${SERVICE_CAMEL}.py started with PID: ${PID}"
  fi
fi


# vim: tabstop=2 shiftwidth=2 textwidth=0 wrapmargin=0 expandtab
