#! /bin/sh
### BEGIN INIT INFO
# Provides:          screenconnect
# Required-Start:    $network $local_fs $remote_fs
# Should-Start:      $named
# Required-Stop:     $network $local_fs $remote_fs
# Should-Stop:       $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 6
### END INIT INFO

SCREENCONNECT_PATH=""

export PATH="$SCREENCONNECT_PATH/App_Runtime/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export MONO_PATH="$SCREENCONNECT_PATH/App_Runtime/lib"
export MONO_CFG_DIR="$SCREENCONNECT_PATH/App_Runtime/etc"
export XDG_CONFIG_HOME="$SCREENCONNECT_PATH/App_Runtime/etc"
export MONO_XMLSERIALIZER_THS=no

SERVICE_SCRIPT="$(readlink -f $0)"
SERVICE_NAME="$(basename $SERVICE_SCRIPT)"
LOCK_FILE_PATH="/tmp/$SERVICE_NAME.lock"
LOG_FILE_PATH="/var/log/$SERVICE_NAME"

run_service() {
	local signalPID=$1
	local signalNumber=$2
	local controllerPID=$(sh -c 'echo $PPID')
	ulimit -n 12288 &>/dev/null

	while true; do
		mono "$SCREENCONNECT_PATH/Bin/Elsinore.ScreenConnect.Service.exe" interactive 0 $signalPID $signalNumber >> "$LOG_FILE_PATH" 2>&1 </dev/null &
		echo "$controllerPID $!" > "$LOCK_FILE_PATH"
		while kill -0 $!; do wait $!; done

		if [ ! "$(awk '{ print $1 }' $LOCK_FILE_PATH 2>/dev/null)" = "$controllerPID" ]; then break; fi
		sleep 5
		if [ ! "$(awk '{ print $1 }' $LOCK_FILE_PATH 2>/dev/null)" = "$controllerPID" ]; then break; fi
	done
}

start_service() {
	local lockFileControllerPID=$(awk '{ print $1 }' "$LOCK_FILE_PATH" 2>/dev/null)

	if ps -p $lockFileControllerPID 2>/dev/null | grep $lockFileControllerPID >/dev/null 2>&1; then
		echo "ScreenConnect is already started, please stop it first."
		exit 0
	fi

	echo "Starting controller process..."

	local signalPID=$$
	local signalNumber=10

	START_TIME=$(date +%s)
	trap "STARTED_FLAG=1" $signalNumber

	(trap "true" HUP; run_service $signalPID $signalNumber) >/dev/null 2>&1 </dev/null &

	echo "Waiting on signal that services have started..."

	while [ -z $STARTED_FLAG ]; do
		CURRENT_TIME=$(date +%s)
		TIME_SINCE_START=$(expr $CURRENT_TIME - $START_TIME)

		if [ $TIME_SINCE_START -gt 60 ]; then
			echo "Timeout waiting for services to start."
			break
		fi

		sleep 1
	done
}

stop_service() {
	local controllerPID=$(awk '{ print $1 }' "$LOCK_FILE_PATH" 2>/dev/null)
	local servicePID=$(awk '{ print $2 }' "$LOCK_FILE_PATH" 2>/dev/null)
	echo "Sending kill signals..."
	kill -9 $controllerPID >/dev/null 2>&1
	kill -9 $servicePID >/dev/null 2>&1
	echo "Waiting for processes to quit..."
	while (kill -0 $controllerPID 2> /dev/null || kill -0 $servicePID 2>/dev/null); do sleep 1; done
}

debug_service() {
	mono --debug "$SCREENCONNECT_PATH/Bin/Elsinore.ScreenConnect.Service.exe" interactive </dev/null
}

case "$1" in
	start)
		start_service
		;;
	restart|reload|force-reload)
		stop_service
		start_service
		;;
	stop)
		stop_service
		;;
	debug)
		stop_service
		debug_service
		;;
	*)
		echo "Usage: $0 start|stop|restart" >&2
		exit 3
		;;
esac
