#!/bin/bash
set -e
set -o pipefail
set -u
# This systemtest tests the plugin functionality
# of the Bareos FD by using the supplied module
# bareos-fd-postgres
#
# The module will backup a postgresql database.
#

TestName="$(basename "$(pwd)")"
export TestName

JobName=backup-bareos-fd
#shellcheck source=../environment.in
. ./environment
. ./database/setup_local_db.sh

# setup local database server
DBNAME="backuptest"
TESTPGHOST="$dbHost"
PSQL="${POSTGRES_BIN_PATH}/psql --host $TESTPGHOST"

[ -d "$TESTPGHOST" ] && rm -R  "$TESTPGHOST"
mkdir -p "$TESTPGHOST"
[ $EUID -eq 0 ] && chown postgres "$TESTPGHOST"

pushd database > /dev/null
setup_local_db "$TESTPGHOST"
# PG_VERSION will be pick from backuped PG data dir
PG_VERSION="$(cut -d '.' -f1 data/PG_VERSION)"
if [ ${PG_VERSION} -ge 15 ]; then
# skip test
 echo "${TestName} test skipped: not compatible with PG >= 15"
 exit 77;
fi
popd > /dev/null

#shellcheck source=../scripts/functions
. "${rscripts}"/functions

# Create Test DB with table and 1 statement
echo "CREATE DATABASE $DBNAME" | ${PSQL} postgres
${PSQL} ${DBNAME} <<<"
CREATE TABLE t(id serial PRIMARY KEY, text VARCHAR(20), created_on TIMESTAMP);
INSERT INTO t (text, created_on) values ('test for FULL backup', current_timestamp);
SELECT * FROM t;
"

start_test

cat <<END_OF_DATA >$tmp/bconcmds
@$out /dev/null
messages
@$out $tmp/log1.out
label volume=TestVolume001 storage=File pool=Full
setdebug level=100 trace=1 timestamp=1 client=bareos-fd
run job=$JobName yes
wait
setdebug level=0 client=bareos-fd
status director
status client
status storage=File
wait
messages
END_OF_DATA

run_bconsole

# Now add data to the database and run an incremental job
echo "INSERT INTO t (text, created_on) values ('test for INCR backup', current_timestamp)" | ${PSQL} ${DBNAME}

cat <<END_OF_DATA >$tmp/bconcmds
@$out /dev/null
messages
@$out $tmp/log1.out
run job=$JobName Level=Incremental yes
wait
END_OF_DATA

run_bconsole
# run another Incr without db changes - should result in empty backup job (only restore object)
run_bconsole

# Now stop database and try a restore
pushd database/ > /dev/null
local_db_stop_server "$TESTPGHOST"
rm -Rf data
rm -Rf wal_archive
echo "------------ stopped"
popd > /dev/null

cat <<END_OF_DATA >$tmp/bconcmds
@$out /dev/null
messages
messages
@$out $tmp/log1.out
restore client=bareos-fd where=/ select all done yes
wait
messages
END_OF_DATA
run_bconsole

check_for_zombie_jobs storage=File
sleep 1

#sometimes the pid file remains
rm -f database/data/postmaster.pid
#empty also pg_wal which will be filled by the restore command
rm -f database/data/pg_wal/*

# use either recovery.conf or recovery.signal
# Those files should exist after restore, the plugin create them
# postgres 11 and lower
restore_command="restore_command = 'cp ${current_test_directory}/database/wal_archive/%f %p'"
if (( ${PG_VERSION} < 12 )); then
  echo "PG_VERSION is ${PG_VERSION} so lower than 12, using recovery.conf"
  recovery_file="${current_test_directory}/database/data/recovery.conf"
else
  # postgres 12+
  echo "PG_VERSION is ${PG_VERSION} so 12+, using postgresql.conf and recovery.signal"
  echo "${restore_command}" >> "${current_test_directory}/database/data/postgresql.conf"
  recovery_file="${current_test_directory}/database/data/recovery.signal"
fi
echo "${restore_command}" >> "${recovery_file}"
[ $EUID -eq 0 ] && chown postgres ${recovery_file}

# start DB again - shall recover to latest possible state
pushd database > /dev/null
local_db_start_server "$TESTPGHOST" || exit 1
popd > /dev/null

i=0
until ${PSQL} ${DBNAME} <<< "SELECT * FROM t" | grep "for INCR"  > $tmp/sql.log  ; do
	echo "waiting for query to succeed"
	sleep 1
  i=$((i+1))
  if [ $i -gt 30 ]; then echo "timeout waiting for query after recovery"; exit 1; fi
done

pushd database/ > /dev/null
local_db_stop_server "$TESTPGHOST"
popd > /dev/null

check_two_logs
if (grep -q "for INCR" $tmp/sql.log)
then
   estat=0
else
   echo "Error: Database rows not found"
   estat=1
fi

end_test
