#!/bin/bash

#########################################
# Name: xsvc
#
# Summary: start/stop xfoce components
#
# Description:
#
# Author: k. headley
#
# Copyright MBARI 2013
#
#########################################

#########################################
# Script configuration defaults
# casual users should not need to change
# anything below this section
#########################################
COMPONENT="none"
ACTION="show"
TEST=""

#msg "Using XFHOME=${XFHOME}"

SDS="${XFHOME}/src/gateway/apps/sds"
SBR="${XFHOME}/src/gateway/apps/sbr"
GW="${XFHOME}/src/gateway/apps/gwrun"
GWT="${XFHOME}/src/gateway/test/testgw"

SDS_ALIAS="sds"
SBR_ALIAS="sbr"
GW_ALIAS="gw"
GWT_ALIAS="gwt"

RUNNER="${XFHOME}/src/scripts/xrun"
LOG_DIR="${XFHOME}/logs"

unset GW_LOG_OPT

MSG_INDENT=4

#################################
# Script variable initialization
#################################
VERBOSE="FALSE"

#################################
# Function Definitions
#################################
#################################
# name: sigTrap
# description: signal trap callback
# will interrupt 
# args: none
#################################
sigTrap(){
    exit 0;
}

#################################
# name: printUsage
# description: print use message
# args: none
#################################
printUsage(){
    echo
    msg "usage: `basename $0` [start|stop|show|help] <service> [args]"
    msg "  service  : ${SDS_ALIAS} ${SBR_ALIAS} ${GW_ALIAS} ${GWT_ALIAS}"
    msg "  args     : arguments for service"
    msg "  -l       : log directory (also passed to gateway)"
    msg "  -V       : verbose output"
    msg "  -h       : print this help message"
    msg ""
}

########################################
# name: vout
# description: print verbose message to stderr
# args:
#     msg: message
########################################
vout(){
    if [ "$VERBOSE" == "TRUE" ]
    then
	msg "$1" >&2
    fi
}

########################################
# name: imsg
# description: echos with indent
# args:
#     msg: message
#  indent: indent level
########################################
imsg(){
  OIFS=$IFS
  IFS=""
  msg_pad="                                        "
  let "msg_indent=${1}"
  shift
  all="${@}"
  printf "%s%s\n" ${msg_pad:0:${msg_indent}} ${all}
  IFS=$OIFS
}

########################################
# name: msg
# description: echos with default indent
# args:
#     msg: message
########################################
msg(){
 imsg $MSG_INDENT "${*}"
}

########################################
# name: exitError
# description: print use message to stderr
# args:
#     msg:        error message
#     returnCode: exit status to return
########################################
exitError(){
    msg >&2
    msg "$1" >&2
    msg >&2
    exit $2
}

########################################
# name: getPID
# description: get PID of target process
# args:
#     process name
########################################
getPID(){
	local pid=`ps -C ${1} -o pid=`
	echo $pid
}

##########################
# Script main entry point
##########################

# Argument processing
if [ "$#" -lt 1 ];then
echo
#    printUsage
#    exit 0
fi

while getopts l:hV Option
do
    case $Option in
    l) LOG_DIR=$OPTARG
       GW_LOG_OPT="-l ${LOG_DIR}"
    ;;
	V ) VERBOSE="TRUE"
	;;
	h) printUsage
	  exit 0
	;;
	*) #exit 0 # getopts outputs error message
	;;
    esac
done


# call sigTrap on INT,TERM or EXIT
# trap sigTrap INT TERM EXIT

# reset trapped signals
# trap - INT TERM EXIT

# shift out all the options
# [OPTIND is the index of the first
# non-opt argument]
let "count = $OPTIND-1"
while [ "${count}" -gt 0 ]
do
	shift;
	let "count -= 1";
done

# should still be a program 
# name remaining. 
if [ "$#" -lt 1 ]
then
 printUsage
 exit 1
fi
 
 # set the action
 ACTION="${1}"
 shift

 COMPONENT="${1}"
 shift

ARGS=${1+"$@"}


if [ "${COMPONENT}" == "${SDS_ALIAS}" ] || [ "${COMPONENT}" == "${SBR_ALIAS}" ] || [ "${COMPONENT}" == "${GW_ALIAS}" ] || [ "${COMPONENT}" == "${GWT_ALIAS}" ]
then

  if [ "${COMPONENT}" == "${GW_ALIAS}" ]
  then
	COMP_NAME=`basename ${GW}`
  elif [ "${COMPONENT}" == "${GWT_ALIAS}" ]
  then
	COMP_NAME=`basename ${GWT}`
  else
    COMP_NAME="${COMPONENT}"
  fi
  
  TARGET_PID=`ps -C ${COMP_NAME} -o pid=`

  if [ "${TARGET_PID}" ]
  then
	IS_RUNNING="Y"
  else
	IS_RUNNING="N"
  fi
  
elif [ "${ACTION}" == "show" ] && [ "${COMPONENT}" != "${SDS_ALIAS}" ] || [ "${COMPONENT}" != "${SBR_ALIAS}" ] || [ "${COMPONENT}" != "${GW_ALIAS}" ] || [ "${COMPONENT}" != "${GWT_ALIAS}" ]
then
  COMPONENT="all"
else
	echo 
	msg "invalid component [${COMPONENT}]"
	msg "use [${SDS_ALIAS}|${SBR_ALIAS}|${GW_ALIAS}|${GWT_ALIAS}]"
	echo
	exit -1
fi

vout "COMPONENT  : ${COMPONENT}"
vout "ARGS       : ${ARGS}"
vout "LOG_DIR    : ${LOG_DIR}"
vout "GW_LOG_OPT : ${GW_LOG_OPT}"
vout "ACTION     : ${ACTION}"
vout "TARGET_PID : ${TARGET_PID}"
vout "IS_RUNNING : ${IS_RUNNING}"
vout "`date +%Y.%m.%d-%H:%M:%S` - COMPONENT=${COMPONENT} PID=${TARGET_PID} ACTION=${ACTION}"


# ////////////////////////
# Must set XFHOME
# ////////////////////////
if [ ! -d "${XFHOME}" ]
then
   echo
   msg "XFHOME environment variable not set - try"
   msg "      cd /path/to/XFHOME"
   msg "      . ./src/scripts/xfenv \`pwd\`"
   printUsage
   exit 1
fi

# ////////////////////////
# Help
# ////////////////////////
if [ "${ACTION}" == "help" ]
then
	
  if [ "${COMPONENT}" == "${SDS_ALIAS}" ]
  then
	HELP_CMD="${SDS} -h"
  elif [ "${COMPONENT}" == "${SBR_ALIAS}" ]
  then
	HELP_CMD="${SBR} -h"
  elif [ "${COMPONENT}" == "${GW_ALIAS}" ]
  then
	HELP_CMD="${GW} -h"
  elif [ "${COMPONENT}" == "${GWT_ALIAS}" ]
  then
	HELP_CMD="${GWT} -h"
  fi
  
  echo
  ${HELP_CMD}
  echo
  exit 0
fi


# ////////////////////////
# Start
# ////////////////////////
if [ "${ACTION}" == "start" ] && [ "${IS_RUNNING}" == "N" ]
then

  msg " starting ${COMPONENT}"
  LOG_NAME="${COMPONENT}.out"
  if [ "${COMPONENT}" == "${SDS_ALIAS}" ]
  then
	CNAME=${SDS}	 
  elif [ "${COMPONENT}" == "${SBR_ALIAS}" ]
  then
	CNAME=${SBR}
  elif [ "${COMPONENT}" == "${GW_ALIAS}" ]
  then
	CNAME=${GW}
    LOG_NAME="${COMPONENT}-out.log"
    if [ "${GW_LOG_OPT}" ]
    then
    ARGS+=" ${GW_LOG_OPT}"
    fi

  elif [ "${COMPONENT}" == "${GWT_ALIAS}" ]
  then
	CNAME=${GWT}
    LOG_NAME="${COMPONENT}-out.log"
    if [ "${GW_LOG_OPT}" ]
    then
    ARGS+=" ${GW_LOG_OPT}"
    fi
  fi
  # start the component
  msg "CMD[$CNAME] ARGS[$ARGS]"
  msg "RUNNER[$RUNNER]"
  test=`${RUNNER} -l ${LOG_DIR}/${LOG_NAME} ${CNAME} ${ARGS}`
  rval=$?
  TARGET_PID=`ps -C $COMPONENT -o pid=`
  msg "`basename ${RUNNER}` returned ${rval} PID [$TARGET_PID]"
 
elif [ "${ACTION}" == "start" ] && [ "${IS_RUNNING}" == "Y" ]
then 
	TARGET_PID=`ps -C $COMPONENT -o pid=`
 echo
 msg "component ${COMPONENT} is already running [PID $TARGET_PID]"
 echo

 #IFS=' '
 #sds_cmd=`ps -C sds -o args=`
 #read -a sds_args<<< $sds_cmd
 #sds_prog=${sds_args[0]}
 #sds_arg1=${sds_args[1]}
 
fi

# ////////////////////////
# Stop
# ////////////////////////

if [ "${ACTION}" == "stop" ] && [ "${IS_RUNNING}" == "Y" ]
then
  echo
  msg "stopping ${COMPONENT} PID[$TARGET_PID]"
  if [ "${TARGET_PID}" -lt 0 ]
  then
	echo
	msg "invalid PID[${TARGET_PID}], exiting"
	echo
	exit 1
  fi
  if [ "${COMPONENT}" == "${SDS_ALIAS}" ] || [ "${COMPONENT}" == "${SBR_ALIAS}" ] || [ "${COMPONENT}" == "${GW_ALIAS}" ] || [ "${COMPONENT}" == "${GWT_ALIAS}" ]
  then
    success=""
	msg "sending INT"
	kill -INT ${TARGET_PID}
	kret=$?
	test=`getPID ${COMP_NAME}`
	msg "kill INT pid[$test] returned [${kret}]"
	
	i=20
	while [ "$i" -gt 0 ]
	do
	test=`getPID ${COMP_NAME}`
	if [ ! "${test}" ]
	then
		msg "${COMP_NAME} stopped"
		exit 0
	fi	
	let "i-=1"
	sleep 1
    done
	
	msg "sending HUP"
	kill -HUP ${TARGET_PID}
	kret=$?
	test=`getPID ${COMP_NAME}`
	msg "kill HUP pid[$test] returned [${kret}]"
	
	i=10
	while [ "$i" -gt 0 ]
	do
	test=`getPID ${COMP_NAME}`
	if [ ! "${test}" ]
	then
		msg "${COMP_NAME} stopped"
		echo
		exit 0
	fi	
	let "i-=1"
	sleep 1
    done
	
	msg "Process did not finish before timeout - try kill -TERM $test"
	echo
	
	exit 1
  fi
elif [ "${ACTION}" == "stop" ] && [ "${IS_RUNNING}" == "N" ]
then 
 echo
 msg "component ${COMPONENT} is not running"
 echo
fi

# ////////////////////////
# Show
# ////////////////////////

if [ "${ACTION}" == "show" ]
then

	echo
	vout "showing ${COMPONENT}"
	
  if [ "${COMPONENT}" == "${SDS_ALIAS}" ] || [ "${COMPONENT}" == "all" ] 
  then
	COMP="${SDS}"
	COMP_NAME=`basename $COMP`
	COMP_PID=`ps -C $COMP_NAME -o pid=`
	if [ "${COMP_PID}" ]
	then
		msg "${SDS_ALIAS} is running PID[$COMP_PID]"
		else
		msg "${SDS_ALIAS} is not running"
	fi
  fi

  if [ "${COMPONENT}" == "${SBR_ALIAS}" ] || [ "${COMPONENT}" == "all" ] 
  then
	COMP="${SBR}"
	COMP_NAME=`basename $COMP`
	COMP_PID=`ps -C $COMP_NAME -o pid=`
	if [ "${COMP_PID}" ]
	then
		msg "${SBR_ALIAS} is running PID[$COMP_PID]"
		else
		msg "${SBR_ALIAS} is not running"
	fi
  fi
	
  if [ "${COMPONENT}" == "${GW_ALIAS}" ] || [ "${COMPONENT}" == "all" ]
  then
	COMP="${GW}"
	COMP_NAME=`basename $COMP`
	COMP_PID=`ps -C $COMP_NAME -o pid=`
	if [ "${COMP_PID}" ]
	then
		msg "${GW_ALIAS}  is running PID[$COMP_PID]"
		else
		msg "${GW_ALIAS}  is not running"
	fi
  fi
  
  if [ "${COMPONENT}" == "${GWT_ALIAS}" ] || [ "${COMPONENT}" == "all" ]
  then
	COMP="${GWT}"
	COMP_NAME=`basename $COMP`
	COMP_PID=`ps -C $COMP_NAME -o pid=`
	if [ "${COMP_PID}" ]
	then
		msg "${GWT_ALIAS} is running PID[$COMP_PID]"
		else
		msg "${GWT_ALIAS} is not running"
	fi
  fi

fi

echo
exit 0
