#!/usr/bin/env bash

set -e

LOGS=$1
DATABASES=$2
SCALE=$3
PARTITIONS=$4

RESTOREDIR=/mnt/pgdata/restored
DEBUG=debug.log
BACKUPS=/mnt/pgdata/backups
PATH_OLD=$PATH
RUNS=1

# number of incremental-backups
NUM_BACKUPS=$(ls $BACKUPS | grep increment | wc -l)

function wait_for_reclaim {
	prev=$(df | grep pgdata | awk '{print $3}')

	while /bin/true; do

		sleep 5;

		curr=$(df | grep pgdata | awk '{print $3}')

		if  [ "$curr" == "$prev" ]; then
			break
		fi

		prev=$curr

	done
}

rm -f parameters.txt

#for p in 0-master; do
for p in 1-alignment 2-clone 3-reconstruct 4-prefetch 5-reconstruct-batch 6-prefetch-batch; do

	for b in $(seq 1 $NUM_BACKUPS); do

		for method in copy copy-file-range; do

			for manifest in on off; do

				for prefetch in on off; do

					if [ "$method" == "copy-file-range" ]; then
						# first two options don't have the copy-file-range option
						if [ "$p" == "0-master" ] || [ "$p" == "1-alignment" ]; then
							continue
						fi
					fi

					if [ "$prefetch" == "on" ]; then
						if [ "$p" == "0-master" ] || [ "$p" == "1-alignment" ] || [ "$p" == "2-clone" ] || [ "$p" == "3-reconstruct" ]; then
							continue
						fi
					fi

					for r in $(seq 1 $RUNS); do

						echo $p $b $method $manifest $prefetch >> parameters.txt

					done

				done

			done

		done

	done

done

sort -R parameters.txt > parameters.random


while IFS= read -r line
do

	IFS=' ' read -a params <<< "$line"

	p="${params[0]}"
	b="${params[1]}"
	method="${params[2]}"
	manifest="${params[3]}"
	prefetch="${params[4]}"

	mkdir -p $LOGS/$p
	rm -Rf $RESTOREDIR/restore-*
	PATH=/var/lib/postgresql/builds/pg-master-$p/bin:$PATH_OLD

	# build the list of backups
	backups="$BACKUPS/full"
	for s in $(seq 1 $b); do
		backups="$backups $BACKUPS/increment-$s"
	done

	OPTIONS=""

	if [ "$manifest" == "off" ]; then
		OPTIONS="$OPTIONS --no-manifest"
	fi

	if [ "$method" == "copy-file-range" ]; then
		OPTIONS="$OPTIONS --copy-file-range"
	fi

	if [ "$prefetch" == "on" ]; then
		OPTIONS="$OPTIONS --prefetch"
	fi

	for r in $(seq 1 $RUNS); do

		echo `date` "build $p combining backups method $method manifest $manifest ($backups)"

		rm -Rf $RESTOREDIR/restore-*

		echo `date` "fstrim"
		sudo fstrim /mnt/pgdata || true

		sync
		wait_for_reclaim

		used_before=$(df /mnt/pgdata | grep pgdata | awk '{print $3}')

		echo `date` $(which pg_combinebackup)

		echo `date` pg_combinebackup -o $RESTOREDIR/restore-$b-$r $OPTIONS $backups

		s=$(date +"%s.%6N")
		pg_combinebackup -o $RESTOREDIR/restore-$b-$r $OPTIONS $backups > $LOGS/$p/debug-$b-$r-$method-$manifest-$prefetch.log 2>&1
		e=$(date +"%s.%6N")
		d=$(echo "$e - $s" | bc)

		used_after=$(df /mnt/pgdata | grep pgdata | awk '{print $3}')

		echo `date` backups combined

		verify=""
		if [ "$manifest" == "on" ]; then
			echo `date` verifying combined backup
			#pg_verifybackup -P -e -m $RESTOREDIR/restore-$b-$r/backup_manifest $RESTOREDIR/restore-$b-$r > $LOGS/$p/verify-$b-$r-$method-$manifest-$prefetch.log 2>&1
			verify=$?
			echo `date` backup verified
		fi

		echo `date` finishing recovery

		# restart the cluster, so finish recovery before checksums check
		#pg_ctl -D $RESTOREDIR/restore-$b-$r -l $LOGS/$p/restore-$b-$r-$method-$manifest-$prefetch.log start > /dev/null 2>&1
		#pg_ctl -D $RESTOREDIR/restore-$b-$r -l $LOGS/$p/restore-$b-$r-$method-$manifest-$prefetch.log stop > /dev/null 2>&1

		sync

		zpool get allocated,bcloneratio,bclonesaved,bcloneused

		echo `date` recovery finished, verifying checksums

		# verify checksums
		#pg_checksums --check $RESTOREDIR/restore-$b-$r > $LOGS/$p/checksums-$b-$r-$method-$manifest-$prefetch.log 2>&1
		checksums=$?

		echo `date` "checksums verified ($checksums)"

		#echo `date` "calculading checksum of restored database"

		# restart the cluster, so finish recovery before checksums check
		#pg_ctl -D $RESTOREDIR/restore-$b-$r -l $LOGS/$p/restore-$b-$r-$method-$manifest-$prefetch.log start > /dev/null 2>&1
		#chsum=$(pg_dumpall | md5sum | awk '{print $1}')
		#pg_ctl -D $RESTOREDIR/restore-$b-$r -l $LOGS/$p/restore-$b-$r-$method-$manifest-$prefetch.log stop > /dev/null 2>&1

		#echo `date` "checksum of restored database: $chsum"

		echo `date` "combinebackup done: " $((size-used)) "KB, $d seconds, checksums $checksums verify $verify"

		echo $DATABASES $SCALE $PARTITIONS $p $manifest $method $prefetch $b $r $d $((used_after-used_before)) $used_before $used_after $checksums >> $LOGS/results.csv 2>&1

	done

done < parameters.random
