#!/bin/sh -
#
# chkconfig:   345 99 01
# description: Starts and stops the OpenNMS @NAME_DISPLAY@ distributed client
# processname: java
#
### BEGIN INIT INFO
# Provides:          @NAME_LC@
# Required-Start:    $network $remote_fs
# Required-Stop:     $network $remote_fs
# Should-Start:      $local_fs
# Should-Stop:       $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: OpenNMS @NAME_DISPLAY@
# Description:       OpenNMS @NAME_DISPLAY@ in a Karaf Container
### END INIT INFO

NAME="@NAME_LC@"
DESC="@NAME_DISPLAY@"
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
CONTAINER_HOME="@INSTPREFIX@"
SYSCONFDIR="@SYSCONFDIR@"
RUNAS="@RUNAS@"
STOP_RETRIES=10
STOP_WAIT=5
PING_REQUIRED=FALSE
PIDFILE="@PIDFILE@"

export NAME DESC PATH

if [ -f /lib/lsb/init-functions ]; then
	# shellcheck disable=SC1090,SC1091
	. /lib/lsb/init-functions
fi

if [ -f /etc/rc.d/init.d/functions ]; then
	# shellcheck disable=SC1090,SC1091
	. /etc/rc.d/init.d/functions
fi

if [ -z "$JAVA_HOME" ]; then
	JAVA_HOME="$("$CONTAINER_HOME/bin/find-java.sh" 1.8.0 11.9.9999)"
fi

if [ -r "$SYSCONFDIR/$NAME" ]; then
	# shellcheck disable=SC1090,SC1091
	. "$SYSCONFDIR/$NAME"
fi

if [ -r "$CONTAINER_HOME/$NAME.conf" ]; then
	# shellcheck disable=SC1090,SC1091
	. "$CONTAINER_HOME/$NAME.conf"
fi

if [ -r "$CONTAINER_HOME/etc/$NAME.conf" ]; then
	# shellcheck disable=SC1090,SC1091
	. "$CONTAINER_HOME/etc/$NAME.conf"
fi

# if $JAVA_OPTS is set at all, Karaf won't process it properly,
# so move everything to $EXTRA_JAVA_OPTS, which is made a part
# of $JAVA_OPTS as the final part of Karaf's initialization.

# shellcheck disable=SC2034
EXTRA_JAVA_OPTS="$JAVA_OPTS $EXTRA_JAVA_OPTS"
unset JAVA_OPTS

# always dump heap if we OOM
EXTRA_JAVA_OPTS="$EXTRA_JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError"

# export any default configurable variables from sysconf
export RUNAS JAVA_MIN_MEM JAVA_MAX_MEM MAX_FD JAVA_HOME JAVA JAVA_DEBUG_OPTS JAVA_DEBUG_PORT EXTRA_JAVA_OPTS CLASSPATH KARAF_DEBUG LD_LIBRARY_PATH

# export any local configurable variables
export NAME DESC PATH CONTAINER_HOME SYSCONFDIR STOP_RETRIES STOP_WAIT

run_as() {
	if [ "$(id -n -u)" "!=" "$RUNAS" ]; then
		DAEMON="$(daemon --user="$RUNAS" true >/dev/null 2>&1 && command -v daemon)"
		RUNUSER="$(runuser -u "$RUNAS" true 2>/dev/null && command -v runuser)"
		if [ -n "$DAEMON" ]; then
			"$DAEMON" --user="$RUNAS" "$@" >/dev/null 2>&1
		elif [ -n "$RUNUSER" ] && [ -x "$RUNUSER" ]; then
			"$RUNUSER" -u "$RUNAS" "$@"
		else
			/usr/bin/sudo -u "$RUNAS" "$@"
		fi
	else
		"$@"
	fi
}

check_upgrade_files() {
	for EXTENSION in rpmnew rpmsave dpkg-dist; do
		if [ "$(find "$CONTAINER_HOME" -name \*."$EXTENSION" 2>/dev/null | wc -l)" -gt 0 ]; then
			cat <<END >&2

WARNING!  You have files that end in .$EXTENSION in your
$CONTAINER_HOME directory.

The format of the original files may have changed since
you modified them before installing a new version.
Please double-check that your configuration files are
up-to-date and delete any leftover .$EXTENSION files or
$DESC will not start.

END
			case "$COMMAND" in
				status)
					# when calling with `status` return 3 for "stopped"
					return 3	# From LSB: 3 - program is stopped
					;;
				*)
					# any other init command should return 6 on error
					return 6	# From LSB: 6 - program is not configured
					;;
			esac
		fi
	done
}

get_root_pid() {
	ROOT_INSTANCE_PID=0
	if [ -f "$CONTAINER_HOME/instances/instance.properties" ];
	then
		ROOT_INSTANCE_PID=$(sed -n -e '/item.0.pid/ s/.*\= *//p' "$CONTAINER_HOME/instances/instance.properties")
	fi
	echo "$ROOT_INSTANCE_PID"
}

is_running() {
	PID=$(get_root_pid)
	if [ "$PID" -ne "0" ] && ps p "$PID" > /dev/null; then
		return 0
	else
		return 1
	fi
}

stop_process() {
	run_as "$CONTAINER_HOME"/bin/stop >/dev/null
}

kill_process() {
	SIGNAL="$1"
	if [ -z "$SIGNAL" ]; then
		SIGNAL="-15"
	fi
	PID=$(get_root_pid)
	if [ "$PID" -gt 0 ]; then
		kill $SIGNAL "$PID"
	fi
}


COMMAND="$1"

case "$COMMAND" in

	start)
		if is_running; then
			echo "$DESC is running."
			exit 0
		fi

		if ! check_upgrade_files; then
			exit $?
		fi

		case "$PING_REQUIRED" in
			[Tt][Rr][Uu][Ee])
				# LSB 4 = insufficient privilege
				"$CONTAINER_HOME/bin/ensure-user-ping.sh" "$RUNAS" || exit 4
				;;
			*)
				QUIET=true "$CONTAINER_HOME/bin/ensure-user-ping.sh" "$RUNAS" || :
				;;
		esac

		if [ ! -d "$CONTAINER_HOME/data/tmp" ]; then
			install -d -m 755 -o "$RUNAS" -g "$RUNAS" "$CONTAINER_HOME/data/tmp"
		fi
		chown -R "$RUNAS:$RUNAS" "$CONTAINER_HOME/data/"
		run_as "$CONTAINER_HOME"/bin/start
		sleep 5
		RET="$?"

		__piddir="$(dirname "$PIDFILE")"
		if [ ! -d "$__piddir" ]; then
			install -d -m 755 -o "$RUNAS" -g "$RUNAS" "$__piddir"
		fi

		# wait 30 seconds for it to write an instance pid
		# shellcheck disable=SC2034
		for COUNT in $(seq 1 6); do
			if is_running; then
				get_root_pid > "$PIDFILE"
				chown "$RUNAS:$RUNAS" "$PIDFILE"
				chmod 640 "$PIDFILE"
				exit "$RET"
			fi
			sleep 5
		done

		exit 1
		;;

	stop)
		if is_running; then
			printf "Stopping %s: " "$DESC"
			STOP_ATTEMPTS=0
			stop_process
			while [ "$STOP_ATTEMPTS" -lt "$STOP_RETRIES" ]; do
				sleep $STOP_WAIT
				if is_running; then
					STOP_ATTEMPTS="$((STOP_ATTEMPTS + 1))"
					kill_process # SIGTERM, "nice" kill
				else
					echo "OK"
					rm -f "$PIDFILE"
					exit 0
				fi
			done
			echo "FAILED"

			printf "Force-killing %s: " "$DESC"
			kill_process -9
			sleep $STOP_WAIT
			if is_running; then
				echo "FAILED"
				exit 1
			fi
			echo "OK"
			rm -f "$PIDFILE"
			exit 0
		else
			echo "$DESC is not running."
			rm -f "$PIDFILE"
			exit 0 # LSB specifies calling "stop" on a stopped service is still a success
		fi
		;;

	restart)
		if ! check_upgrade_files; then
			exit $?
		fi

		$0 stop >/dev/null 2>&1
		sleep 2
		$0 start
		exit $?
		;;

	try-restart)
		if is_running; then
			echo "$DESC is not running."
			exit 0
		else
			$0 restart
			exit $?
		fi
		;;


	force-reload)
		$0 try-restart
		exit $?
		;;

	status)
		run_as "$CONTAINER_HOME"/bin/status >/dev/null
		RETVAL="$?"
		if [ $RETVAL -eq 0 ]; then
			echo "$DESC is running."
			exit 0
		else
			echo "$DESC is stopped."
			exit 3
		fi
		;;

	*)
		echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" >&2
		exit 1
		;;
esac
