#!/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"
popd > /dev/null

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

# 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;
"
PSQL_VERSION=$(${PSQL} -qtAX ${DBNAME} <<< "SHOW server_version;" | sed 's/\..*//g')

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_bareos "$@"

# 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
stop_bareos
sleep 1

#sometimes the pid file remains
rm -f database/data/postmaster.pid

# Create a recovery.conf
# This may become a plugin feature later on
# postgres 11 and lower
# bc returns 1 if true, 0 if false so we need to negate
if [ $(bc -l <<< "${PSQL_VERSION} < 12") -eq "1" ]; then
  echo "PSQL is ${PSQL_VERSION} so lower than 12, using recovery.conf"
  echo "restore_command = 'cp $current_test_directory/database/wal_archive/%f %p'" > $current_test_directory/database/data/recovery.conf
  [ $EUID -eq 0 ] &&  chown postgres database/data/recovery.conf
else
  # postgres 12+
  echo "PSQL is ${PSQL_VERSION} so 12+, using postgresql.conf and recovery.signal"
  touch $current_test_directory/database/data/recovery.signal
  echo "restore_command = 'cp $current_test_directory/database/wal_archive/%f %p'" >> database/data/postgresql.conf
  [ $EUID -eq 0 ] &&  chown postgres database/data/postgresql.conf
fi
# 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
