#!/bin/bash
set -e
set -o pipefail
set -u
#
# Cancel a backup and check that metadata is still saved with checkpoints.
#
TestName="$(basename "$(pwd)")"
export TestName

#shellcheck source=../../environment.in
. ./environment

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

start_test

backup_log=$tmp/cancel-backup-checkpoints.out
restore_log=$tmp/cancel-restore-checkpoints.out
restore_directory=$tmp/cancel-checkpoints-restore-directory

rm -f "$backup_log"
rm -f "$restore_log"
rm -rf "$restore_directory"

slowjob="slow-backup-bareos-fd"

cat <<END_OF_DATA >"$tmp/bconcmds"
@$out ${NULL_DEV}
messages
setdebug level=100 trace=1 all
@$out $backup_log
run job=$slowjob fileset=bigfileset level=Full yes
quit
END_OF_DATA

run_bconsole

timeout=0
timed_checkpoint=""
volume_checkpoint=""

while [[ ${timeout} -lt 30 ]] && [[ -z $timed_checkpoint || -z $volume_checkpoint ]]; do
  timed_checkpoint=$(grep -m 1 'Doing timed backup checkpoint. Next checkpoint in 3 seconds' "$messagesfile" || :)
  volume_checkpoint=$(grep -m 1 'Volume changed, doing checkpoint:' "$messagesfile" || :)
  sleep 1
  ((++timeout))
done

# Check that a timed checkpoint was triggered
if [[ -z $timed_checkpoint ]]; then
  echo "Timed checkpoint was not triggered!"
  estat=1
fi

# Check that a checkpoint happened on a volume change
if [[ -z $volume_checkpoint ]]; then
  echo "Checkpoint was not triggered on volume changes!"
  estat=2
fi

slowjobid=$(grep 'Job queued. JobId=' "$backup_log" | sed -n -e 's/^.*JobId=//p')

cat <<END_OF_DATA >"$tmp/bconcmds"
@$out $backup_log
cancel jobid=${slowjobid}
wait
messages
@$out $restore_log
restore jobid=${slowjobid} where=$restore_directory all done yes
wait
messages
setdebug trace=0 all
quit
END_OF_DATA

run_bconsole

# Check that a cancel was triggered
expect_grep "Termination:            Backup Canceled" \
  "$backup_log" \
  "Job was not canceled!"

NumberOfBackedUpFiles=0
while read -a nums; do
  for num in "${nums[@]}"; do
    ((NumberOfBackedUpFiles += num))
  done
done <<<"$(grep "entries start" "$backup_log" | cut -d" " -f12)"

# Check that part of the files were written despite the cancel
if [ "$NumberOfBackedUpFiles" -le 0 ]; then
  echo "Checkpoint files were not correctly saved! Number of backed up files: ${NumberOfBackedUpFiles}" >&2
  estat=1
fi

# Check that the restore of a canceled backup works fine
expect_grep "Termination:.*Restore OK" \
  "$restore_log" \
  "Restore is not OK."

expect_grep "Files Restored:         ${NumberOfBackedUpFiles}" \
  "$restore_log" \
  "Restore of canceled job did not go well!"

restorepath="$restore_directory/$tmp/bigdata"
restorepath=$(remove_colon_from_windows_path "$restorepath")

# Certain systems do not support multiple types for find (-type f,l)
NumberOfFilesRestored=$(find "$restorepath" -type f | wc -l)
NumberOfLinksRestored=$(find "$restorepath" -type l | wc -l)
NumberOfDirectoriesRestored=$(find "$restorepath" -type d | wc -l)
RestoredItems=$((NumberOfFilesRestored + NumberOfLinksRestored + NumberOfDirectoriesRestored))

# Check that the restored files are actually there
if [ ${RestoredItems} -lt "${NumberOfBackedUpFiles}" ]; then
  echo "Actual restored items count not met. Items (files, links, directories) found = ${RestoredItems} , backed up files = ${NumberOfBackedUpFiles}" >&2
  estat=1
fi

end_test
