#!/bin/bash

cmd_x2golistsessions=x2golistsessions
if [ "$(id -u)" = 0 ] ; then
	cmd_x2golistsessions=x2golistsessions_root
fi

# Make the script fail when a command fails
set -e

# Settings variables go here
grace_time=""
dry_run=""
verbosity=1

show_help() {
cat <<EOF
Usage: foxde-stop-old-x2go-sessions

Fetches x2go-sessions and stops those that have not been used for longer than a given grace time.

Options:
--gracetime <timespan>
	The timespan consists of space seperated value-unit pairs.
	Example: 1s 1m 1h 1d

--quiet
-v, --verbose
-vv
	Set the level of verbosity for the output.

--dry-run
	Only list the sesions that would be stopped.

--hostname <hostname>
	Pretend to be on another host (useful with --dry-run for testing)
EOF
}

while [[ "$#" -gt 0 ]]; do
	case "$1" in
		--gracetime)
			grace_time="$2"
			shift 2;;

		--dry-run)
			dry_run="y"
			shift 1;;

		-q|--quiet)
			verbosity=0
			shift 1;;

		-v|--verbose)
			verbosity=2
			shift 1;;

		-vv)
			verbosity=3
			shift 1;;

		--hostname)
			hostname="$2"
			shift 2;;

		--help) show_help; exit 0;;
		*) printf "Unknown option: %s\n" "$1"; exit 1;;
	esac
done

log() {
	if [ "$1" -le "$verbosity" ] ; then
		format="$2"
		shift 2
		# shellcheck disable=SC2059
		printf "$format\n" "$@"
	fi
}

time_to_seconds() {
	awk -v'RS= ' '
		1 { sub(/\n/, "")}
		/^\s*$/{ valid=1 }
		/^[0-9]+[smhd]$/ {
			valid=1;
			n=substr($0, 1, length($0-1));
			u=substr($0, length($0));
			if (u=="s") {
				total += n
			} else if (u=="m") {
				total += n*60
			} else if (u=="h") {
				total += n*3600
			} else if (u=="d") {
				total += n*3600*24
			}
		}
		1 {
			if (valid) {
				valid=0
			} else {
				print "Can not parse »" $0 "« as timespan" > "/dev/stderr";
				exit 1
			}
		}
		END { print total }
	'
}

grace_time_seconds="$(printf %s "$grace_time" | time_to_seconds)"

log 3 "gracetime: $grace_time_seconds seconds"

if [ -z "$grace_time_seconds" ] ; then
	echo "Please configure a gracetime!"
	exit 1
fi

now="$(date +%s)"
[ -n "$hostname" ] || hostname="$(hostname)"

sessions_to_stop="$( $cmd_x2golistsessions | awk -v"grace_time_seconds=$grace_time_seconds" -v"now=$now" -v"host=$hostname" -F'|' '
	$5=="S" && $4==host {
		"date +%s --date " $11 | getline last_session_use ;
		time_inactive = now - last_session_use ;
		if (time_inactive > grace_time_seconds) {
			print
		}
	}
')"

if [ -n "$dry_run" ] ; then
	log 1 "Would stop %d sessions." "$( printf %s "$sessions_to_stop" | wc -l )"
else
	log 1 "Stopping %d sessions." "$( printf %s "$sessions_to_stop" | wc -l )"
fi

IFS='
'
for session in $sessions_to_stop; do
	pid="$(printf %s "$session" | cut -d'|' -f1)"
	if [ "$verbosity" -ge 2 ] ; then
		user="$(printf %s "$session" | cut -d'|' -f12)"
		ip="$(printf %s "$session" | cut -d'|' -f8)"
		last_used="$(printf %s "$session" | cut -d'|' -f11)"
		log 2 "Stopping session: $pid $user@$ip last used: $last_used"
	fi
	[ -n "$dry_run" ] || kill "$pid"
done


