#!/bin/sh
die() { printf '%s\n' "$*" >&2; exit 1; }
dietail() {
	printf '%s\n' "$*" >&2
	printf 'tail %s:\n' "$LOG" >&2
	tail "$SERVERBASE/logs/$LOG"
	exit 1
}
[ $# -ge 1 ] || die "Syntax: $(basename "$0") <server version> [--test] [<additional parameters for wesnothd>]"
set -o nounset
set -o noclobber

SERVER=$1
SERVERBASE="$HOME/servers/$SERVER"
[ -d "$SERVERBASE" ] || die "Server '$SERVER' not found."
[ -d "$SERVERBASE"/logs ] || mkdir "$SERVERBASE"/logs
[ -d "$SERVERBASE"/replays ] || mkdir "$SERVERBASE"/replays

shift
if [ $# -ge 1 ] && [ "$1" = "--test" ]; then
	shift
	cd "$SERVERBASE"/build || exit 1
	bin/wesnothd-$SERVER -c "$SERVERBASE"/wesnothd.cfg --port 15001 "$@"
	# remove the socket so it looks like we never ran the server
	rm var/run/socket
	exit 0
fi

PORT=15000
case $SERVER in
1.4|1.8)
       PORT=14998
       set -- --threads 8;;
1.6)   PORT=14999
       set -- --threads 8;;
1.5*)  PORT=14999
       set -- --threads 16;;
1.7*)  PORT=14997
       set -- --threads 16;;
1.9*|1.10*)
       PORT=14996
       set -- --threads 8;;
1.12*)
       set -- --threads 30;;
1.1[346]*)
       set -- --keepalive;;
trunk)
       set -- --keepalive --log-debug=sql_executor;;
esac

ulimit -Ss 2048
ulimit -c unlimited

# send the standard server message to the appropriate server when killing it with ctrl+c
#trap "$HOME/bin/send_server_message $SERVER; sleep 2; echo -n 'terminated: '; date; exit 0" INT
trap 'printf "terminated: "; date; exit' INT

while true
do
	cd "$SERVERBASE"/build || exit 1
	[ -x bin/wesnothd-$SERVER ] || die "Executable 'bin/wesnothd-$SERVER' not found."

	DATE=$(date +"%Y%m%d-%H%M%S")
	[ -r "$SERVERBASE"/redirect.cfg ] && PORT=$(sed -nE '/port=/s/[[:blank:]]*port="?([0-9]+)"?/\1/p' "$SERVERBASE"/redirect.cfg)
	BUILDDIR=$(readlink "$SERVERBASE"/build)
	#REV=r$(echo $BUILDDIR | sed -nre "s,.*wesnothd-svn-([0-9:SM]+)_$SERVER$,\1,p")
	REV=${BUILDDIR#*wesnothd-*-git-}
	LOG="wesnothd.$DATE.$REV.log"
	bin/wesnothd-$SERVER -c "$SERVERBASE"/wesnothd.cfg --port "$PORT" "$@" > "$SERVERBASE/logs/$LOG" 2>&1 &
	PID=$!
	trap 'kill -s INT "$PID"; trap - INT; kill -s INT "$$"' INT # kill backgrounded wesnothd on INT and properly die from the signal
	echo "started $SERVER server with command: 'wesnothd-$SERVER -c \"$SERVERBASE\"/wesnothd.cfg --port $PORT $*' (commit: $REV, pid: $PID) logging to: $LOG"
	# wait a bit in case the process dies immediately
	sleep 5
	if ps -p $PID > /dev/null 2>&1
	then # create some convenient links
		ln -s "$SERVERBASE/logs/$LOG" "$LOG.$PID"
		rm -f "$SERVERBASE"/old.log "$SERVERBASE"/old.pid
		mv "$SERVERBASE"/current.log "$SERVERBASE"/old.log > /dev/null 2>&1
		mv "$SERVERBASE"/current.pid "$SERVERBASE"/old.pid > /dev/null 2>&1
		echo $PID > "$SERVERBASE"/current.pid
		ln -s "logs/$LOG" "$SERVERBASE"/current.log
	fi

	# wait for the server to terminate
	wait $PID
	EXIT_CODE=$?
	printf '%s wesnothd exited with code: %s\n' "$(date +'%Y%m%d %T')" "$EXIT_CODE"
	trap - INT
	# need to use the recorded path since the build/ symlink might have changed
	mv "$SERVERBASE/$BUILDDIR/gmon.out" "$SERVERBASE/$BUILDDIR/gmon.$DATE.$REV.out" > /dev/null 2>&1
	# check for return code if not zero or 98 (port in use) the server should be restarted
	case $EXIT_CODE in
	0)   exit ;;
	98|127|128) dietail ;; #Could not bind to port #Command not found #Invalid argument to exit
	esac

	printf '%s tail %s:\n'  "$(date +'%Y%m%d %T')" "$LOG"
	tail "$SERVERBASE/logs/$LOG"
	echo
done
