#!/bin/bash
#
#     This file is part of the Squashtest platform.
#     Copyright (C) 2010 - 2011 Squashtest TM, Squashtest.org
#
#     See the NOTICE file distributed with this work for additional
#     information regarding copyright ownership.
#
#     This is free software: you can redistribute it and/or modify
#     it under the terms of the GNU Lesser General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     this software is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU Lesser General Public License for more details.
#
#     You should have received a copy of the GNU Lesser General Public License
#     along with this software.  If not, see <http://www.gnu.org/licenses/>.
#
#
# /etc/init.d/squash-tm
# Red Hat 5 compatible squash-tm startup script.
#
# Author: Jean-Marc BELORGANE (HENIX) <jbelorgane@henix.fr>
#
### BEGIN INIT INFO
# Provides:          squash-tm
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: Start squash-tm at boot time
# Description:       Controls the Squash TM service
### END INIT INFO
#
# Do NOT "set -e"


# Main variables
PATH=/sbin:/usr/sbin:/bin:/usr/bin                   # PATH should only include /usr/* if it runs after the mountnfs.sh script
DESC="Squash TM Service"                             # Script description
NAME="squash-tm"                                     # Script name
SCRIPT_NAME="`pwd`/${NAME}"                          # Script service name
PID_DIR="/var/run"                                   # PID directory
PID_FILE="${PID_DIR}/${NAME}.pid"                    # PID file
JAVA="`which java`"                                  # Java location 
REQUIRED_JAVA_VERS=1.7                               # Java required version, do not configure a third digit here 
DAEMON=${JAVA}                                       # Daemon script

# Default variables also present in squash-tm default configuration file
SQUASH_HOME=/usr/lib/squash-tm                       # Squash home directory
SQUASH_USER="${NAME}"                                # User id to be invoked instead of root
SQUASH_GROUP="${NAME}"                               # Group id to be invoked instead of root
JAR_NAME="squash-tm.war"                             # Java main library
HTTP_PORT=8080                                       # Port for HTTP connector (default 8080; disable with -1)
# Default directory parameters
BUNDLES_DIR="/usr/lib/squash-tm/bundles"             # Bundles directory
CACHE_DIR="/var/cache/squash-tm"                     # Cache directory
LUCENE_DIR="/var/cache/squash-tm/lucene-indexes"     # Cache directory
CONF_DIR="/etc/squash-tm"                            # Configurations directory
LOG_DIR="/var/log/squash-tm"                         # Log directory
TOMCAT_HOME="/var/lib/squash-tm"                     # Tomcat home and work dir
TMP_DIR="/var/tmp"                                   # Java temp dir
PLUGINS_DIR="/usr/lib/squash-tm/plugins"             # plugins directory
# Default database parameters
DB_URL="jdbc:h2:///var/lib/squash-tm/data/squash-tm" # DataBase URL
DB_TYPE="h2"                                         # DataBase driver
DB_USERNAME="sa"                                     # DataBase username
DB_PASSWORD="sa"                                     # DataBase password
#
SQUASH_CONFIG=""                                     # Squash config file


# Load environments
if [ -r /etc/default/locale ]
then
	. /etc/default/locale
	export LANG LANGUAGE
elif [ -r /etc/environment ]
then
	. /etc/environment
	export LANG LANGUAGE
fi

# Source function library.
. /etc/init.d/functions

# Check for existence of needed config file and read it
SQUASH_CONFIG=/etc/sysconfig/${NAME}
[ ! -e "${SQUASH_CONFIG}" ] && { 
	echo "${NAME}: ERROR: ${SQUASH_CONFIG} not existing!";
	if [ "$1" = "stop" ]; then exit 0;
	else exit 6; 
	fi; 
}
[ ! -r "${SQUASH_CONFIG}" ] && { 
	echo "${NAME}: ERROR: ${SQUASH_CONFIG} not readable!"
	echo "Perhaps you forgot 'sudo'?";
	if [ "$1" = "stop" ]; then exit 0;
	else exit 6; 
	fi; 
}

# Read configuration variables file if it is present
[ -f "${SQUASH_CONFIG}" ] && {
	. "${SQUASH_CONFIG}"
	[ -n "${SQUASH_HOME}" ]
}

# Set up environment accordingly to the configuration settings
[ -n "${SQUASH_HOME}" ] || { 
	echo "${NAME}: ERROR: SQUASH_HOME not configured in ${SQUASH_CONFIG}!";
	if [ "$1" = "stop" ]; then exit 0;
	else exit 6; 
	fi; 
}
[ -d "${SQUASH_HOME}" ] || { 
	echo "${NAME}: ERROR: SQUASH_HOME directory does not exist: ${SQUASH_HOME}";
	if [ "$1" = "stop" ]; then exit 0;
	else exit 1; 
	fi; 
}

# Check for missing binaries (stale symlinks should not happen)
[ ! -r "${SQUASH_HOME}/bundles/${JAR_NAME}" ] && { 
	echo "${NAME}: ERROR: ${JAR_NAME} not installed!"; 
	if [ "$1" = "stop" ]; then exit 0;
	else exit 5; 
	fi; 
}

# Check if java exists
JAVA_EXISTS=`${JAVA} -version 2>&1 | grep version`
[ $? -eq 127 -o -z "${JAVA}" ] && {
	echo "${NAME}: ERROR: Java not found!"
	echo "Please ensure that java is in \$PATH."
	if [ "$1" = "stop" ]; then exit 0;
	else exit -1; 
	fi; 
}

# Check if the version is high enough
NUM_REQUIRED_JAVA_VERS=`echo ${REQUIRED_JAVA_VERS} | sed 's/\./0/g'`
JAVA_VERS=`echo ${JAVA_EXISTS} | cut -d " " -f 3  | sed 's/\"//g' | cut -d "." -f 1,2 | sed 's/\./0/g'`
[ ${JAVA_VERS} -lt ${NUM_REQUIRED_JAVA_VERS} ] && {
	echo "${NAME}: ERROR: Your JRE does not meet the requirements!"
	echo "Please install a new JRE, required version ${REQUIRED_JAVA_VERS}."
	if [ "$1" = "stop" ]; then exit 0;
	else exit -2; 
	fi; 
}

# Last settings
DAEMON_ARGS="${JAVA_ARGS} -server -Djava.io.tmpdir=${TMP_DIR} -Dlogging.dir=${LOG_DIR} -jar ${JAR_NAME} --spring.profiles.active=${DB_TYPE} --spring.config.additional-location=${CONF_DIR}/ --spring.config.name=application,squash.tm.cfg --squash.path.root=${SQUASH_HOME} --squash.path.bundles-path=${BUNDLES_DIR} --squash.path.plugins-path=${PLUGINS_DIR} --server.port=${HTTP_PORT} --server.tomcat.basedir=${TOMCAT_HOME} --spring.jpa.properties.hibernate.search.default.indexBase=${LUCENE_DIR} --logging.config=${CONF_DIR}/log4j2.xml"

export _JAVA_OPTIONS="-Dspring.datasource.url=${DB_URL} -Dspring.datasource.username=${DB_USERNAME} -Dspring.datasource.password=${DB_PASSWORD} -Duser.language=en"

JAVA_CMD="cd ${BUNDLES_DIR} && ${JAVA} ${DAEMON_ARGS}"


# Function that checks the tcp port
check_tcp_port() 
{
	local service=$1
	local assigned=$2
	local default=$3

	if [ -n "${assigned}" ]
	then
		port=${assigned}
	else
		port=${default}
	fi

	count=$(netstat --listen --numeric-ports | grep -c \:${port}[[:space:]]) || count=$(ss -ltn | grep -c ":${port} ")
	[ ${count} -ne 0 ] && {
		failure
		echo
		echo "${NAME} : ERROR : The selected ${service} port (${port}) seems to be in use by another program!"
		echo "Please select another port to use for ${NAME}."
		return 1
	}
	return 0
}


# Function that starts/stops the daemon/service
start_stop_daemon()
{
	# Test syntax.
	local gotbase= force= nicelevel corelimit
	local pid base= user= nice= bg= pid_file=
	nicelevel=0

	while [ "$1" != "${1##[-+]}" ]; do
		case $1 in
			'')	echo $"$0: Usage: start_stop_daemon [+/-nicelevel] {program}"
				return 1
				;;
			--check)
				base=$2
				gotbase="yes"
				shift 2
				;;
			--check=?*)
				base=${1#--check=}
				gotbase="yes"
				shift
				;;
			--user)
				user=$2
				shift 2
				;;
			--user=?*)
				user=${1#--user=}
				shift
				;;
			--pidfile)
				pid_file=$2
				shift 2
				;;
			--pidfile=?*)
				pid_file=${1#--pidfile=}
				shift
				;;
			--force)
				force="force"
				shift
				;;
			[-+][0-9]*)
				nice="nice -n $1"
				shift
				;;
			*)	echo $"$0: Usage: start_stop_daemon [+/-nicelevel] {program}"
				return 1
				;;
		esac
	done

	# Save basename.
	[ -z "$gotbase" ] && base=${1##*/}

	# See if it's already running. Look *only* at the pid file.
	__pids_var_run "$base" "$pid_file"

	[ -n "$pid" -a -z "$force" ] && return

	# make sure it doesn't core dump anywhere unless requested
	corelimit="ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}"
	
	# if they set NICELEVEL in /etc/sysconfig/foo, honor it
	[ -n "${NICELEVEL:-}" ] && nice="nice -n $NICELEVEL"
	
	# Echo daemon
	[ "${BOOTUP:-}" = "verbose" -a -z "${LSB:-}" ] && echo -n " $base"

	# And start it up.
	if [ -z "$user" ]; then
		$nice /bin/bash -c "$corelimit >/dev/null 2>&1 ; $*"
	else
		#$nice runuser -s /bin/bash - $user -c "$corelimit >/dev/null 2>&1 ; $*"
		$nice runuser -s /bin/bash $user -c "$corelimit >/dev/null 2>&1 ; $*"
	fi
	[ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup"
}


# Make sure we run as root
[ `id -u` -ne 0 ] && {
	echo "${NAME} : ERROR : The ${NAME} init script can only be run as root!";
	exit 1;
}


#
# Main process
#
RETVAL=0
case "$1" in

	start)
		echo -n "Starting ${DESC} "

		# Verify that the squash-tm port is not already in use, jetty does not exit
		# even for BindException
		check_tcp_port "http" "${HTTP_PORT}" "8080" || exit 1

		start_stop_daemon --user "${SQUASH_USER}" --pidfile "${PID_FILE}" ${JAVA_CMD} > /dev/null 2>&1 &
		RETVAL=$?
		if [ ${RETVAL} -eq 0 ]; then
			sleep 3
			success
			# Just in case we fail to find it
			[ ! -f "${PID_FILE}" ] && echo > "${PID_FILE}"  
			# Get PID
			/bin/ps -fu "${SQUASH_USER}" | grep "${JAR_NAME}" | grep -v "cd ${BUNDLES_DIR} &&" | grep -v grep | tail -1 | while read _user _pid _ppid _other;
			do
				# Save PID in PID_FILE
				echo ${_pid} > "${PID_FILE}"
			done
			chown ${SQUASH_USER}:${SQUASH_GROUP} ${PID_FILE}
		else
			failure
		fi
		echo
		;;

	stop)
		echo -n "Shutting down ${DESC} "
		killproc -p ${PID_FILE} ${NAME}
		RETVAL=$?
		echo
		;;

	try-restart)
		$0 status
		if test $? = 0; then
			$0 restart
		else
				: # Not running is not a failure.
		fi
		;;

	restart)
		$0 stop
		sleep 3
		$0 start
		;;

	status)
		status -p ${PID_FILE} ${NAME}
		RETVAL=$?
		;;

	*)
		echo "Usage: ${SCRIPT_NAME} {start|stop|status|try-restart|restart}"
		exit 3
		;;
	esac
exit ${RETVAL}

