#!/usr/bin/env bash
#
# Script that determines whether it is time to run a backup.

echo "Running timer script: $@"

client="$1" ; shift
current="$1" ; shift
storage_dir="$1" ; shift
reserved1="$1" ; shift
reserved2="$1" ; shift
interval="$1" ; shift
timestamp="$current/timestamp"

# A 'backup' file placed in the storage directory tells this script that
# a backup needs to be done right now.
# This gives the 'server initiates a manual backup' feature.

manual_file="$storage_dir/$client/backup"
if [ -f "$manual_file" ] ; then
	echo "Found $manual_file"
	echo "Do a backup of $client now"
	rm -f "$manual_file"
	exit 0
fi

# The rest of the arguments, if any, should be timebands.
# Set LANG=C and LC_TIME=C so that 'date' returns English day names.
curdayhour=$(LANG=C LC_TIME=C date +"*%a*%H*")
intimeband=0 # If no timebands given, default to not OK.
while [ "$#" -gt 0 ] ; do
	intimeband=0
	timeband="$1"
	case "$timeband" in
		$curdayhour|always)
			echo "In timeband: $timeband"
			intimeband=1
			break
			;;
		*)
			echo "Out of timeband: $timeband"
			;;
	esac
	shift
done

get_intervals()
{
	if [ ! -e "$current" ] ; then
		echo "No prior backup of $client"
		return 0
	fi
	if [ ! -f "$timestamp" ] ; then
		echo "$0: Timestamp file missing for $client."
		return 0
	fi
	if [ -z "$interval" ] ; then
		echo "$0: No time interval given for $client."
		return 0
	fi

	case "$interval" in
	  [0-9]*s) i=${interval%s*} ; intervalsecs=$i ;;
	  [0-9]*m) i=${interval%m*} ; intervalsecs=$((i*60)) ;;
	  [0-9]*h) i=${interval%h*} ; intervalsecs=$((i*60*60)) ;;
	  [0-9]*d) i=${interval%d*} ; intervalsecs=$((i*60*60*24)) ;;
	  [0-9]*w) i=${interval%w*} ; intervalsecs=$((i*60*60*24*7)) ;;
	  [0-9]*n) i=${interval%n*} ; intervalsecs=$((i*60*60*24*30)) ;;
	  *) echo "$0: interval $interval not understood for $client."
		return 0 ;;
	esac

	if [ -z "$intervalsecs" ] ; then
		echo "$0: interval $interval not understood for $client."
		return 0
	fi

	read junk ts < "$timestamp"

	if   ! secs=$(LANG=C LC_TIME=C date +%s -d "$ts") \
	  || ! now=$(LANG=C LC_TIME=C date +"%Y-%m-%d %H:%M:%S") \
	  || ! nowsecs=$(LANG=C LC_TIME=C date +%s -d "$now")
	then
		echo "$0: Date command returned error for $client."
		return 0
	fi

	min_timesecs=$((secs+intervalsecs))

	# GNU coreutils 'date' command should accept the following (even
	# slightly old versions).
	if ! min_time=$(LANG=C LC_TIME=C date -d "Jan 1, 1970 00:00:00 +0000 + $min_timesecs seconds" +"%Y-%m-%d %H:%M:%S")
	then
		# FreeBSD 'date' will return an error with the above, so try
		# a version that FreeBSD 'date' should be happy with.
		if ! min_time=$(LANG=C LC_TIME=C date -r $min_timesecs +"%Y-%m-%d %H:%M:%S")
		then
			echo "$0: Date command returned error for $client."
			return 0
		fi
	fi

	echo "Last backup: $ts"
	echo "Next after : $min_time (interval $interval)"

	return 1
}

if [ "$intimeband" = "0" ] ; then
	get_intervals
	exit 1
fi

if get_intervals ; then
	echo "Do a backup of $client now."
	exit 0
fi

if [ "$min_timesecs" -lt "$nowsecs" ] ; then
	echo "$min_time < $now."
	echo "Do a backup of $client now."
	exit 0
fi

echo "Not yet time for a backup of $client"

exit 1
