#!/bin/bash

#   BAREOS® - Backup Archiving REcovery Open Sourced
#
#   Copyright (C) 2025-2026 Bareos GmbH & Co. KG
#
#   This program is Free Software; you can redistribute it and/or
#   modify it under the terms of version three of the GNU Affero General Public
#   License as published by the Free Software Foundation and included
#   in the file LICENSE.
#
#   This program is distributed in the hope that it will be useful, but
#   WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#   Affero General Public License for more details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
#   02110-1301, USA.

# This testrunner performs a label, release and autoselect of drive.

set -e
set -o pipefail
set -u

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

#shellcheck source=../../environment.in
. ./environment
#shellcheck source=test-config.in
. ./test-config

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

start_test

on_error()
{
  local lc="${BASH_COMMAND}"
  echo "Error occurred in testrunner script [${lc}]"
  export estat=1
  exit 1
}
trap 'on_error' ERR

echo "Set debug on the Tape-Storage daemon"
tracefile="$(bin/bconsole <<< "setdebug level=200 trace=1 storage=Tape-0" | awk -F"tracefile=" '/^3000/ {print $2}')"
: >"${tracefile}" # clear tracefile

echo "Label barcodes"
for i in $(seq ${NUMBER_OF_POOLS}); do
  pool=$((i - 1)) #counts from 0
  for j in $(seq ${NUMBER_OF_TAPES_PER_POOL}); do
    slot=$((j + pool * NUMBER_OF_TAPES_PER_POOL)) #counts from 1
    bin/bconsole <<< "label barcodes slot=${slot} drive=0 pool=Full-${pool} storage=Tape-0 yes" | grep -E "(OK label|already exists)"
  done
done

# create the test backup jobs
rm -f ${tmp}/bconsole_backup_jobs_spooling

spooling="spooldata=yes"
for i in $(seq ${NUMBER_OF_TEST_ROUNDS}); do
  for j in $(seq ${NUMBER_OF_POOLS}); do
    cat << EOF >> "${tmp}/bconsole_backup_jobs_spooling"
run job=backup-bareos-fd level=Full storage=Tape-0 pool=Full-$((j - 1)) ${spooling} yes
status dir
EOF
    if [ $((NUMBER_OF_SPOOLING_JOBS_PER_ROUND - j)) -le 0 ]; then
      spooling=""
    fi
  done
done

# start all the jobs
bin/bconsole < ${tmp}/bconsole_backup_jobs_spooling

DevicesFromConfig=$(sed -n -e 's/^.*Device=//p' ${current_test_directory}/etc/bareos/bareos-sd.d/autochanger/autochanger.conf)
tapedevices=($DevicesFromConfig)

rm -f ${runner_tmp}/log-label-release-autoselect-no.out
# set devices to `autoselect = no` and wait for jobs to finish
cat <<END_OF_DATA >"${tmp}/bconcmds"
@$out ${runner_tmp}/log-label-release-autoselect-no.out
setdevice storage=Tape-0  device=${tapedevices[0]} autoselect=no
wait
messages

label barcodes slot=8 drive=0 pool=Full-0 storage=Tape-0 yes
setdevice storage=Tape-0 device=${tapedevices[0]} autoselect=yes
wait
messages
quit
END_OF_DATA

run_bconsole

# Redo the backup to check if drive 0 is still being used
rm -f ${tmp}/bconsole_backup_jobs
echo "@$out ${runner_tmp}/log-second-backups.out" >> ${tmp}/bconsole_backup_jobs

spooling="spooldata=yes"
for i in $(seq ${NUMBER_OF_TEST_ROUNDS}); do
  for j in $(seq ${NUMBER_OF_POOLS}); do
    cat <<EOF >> ${tmp}/bconsole_backup_jobs
run job=backup-bareos-fd level=Full storage=Tape-0 pool=Full-$((j - 1)) ${spooling} yes
status dir
EOF
    if [ $((NUMBER_OF_SPOOLING_JOBS_PER_ROUND - j)) -le 0 ]; then
      spooling=""
    fi
  done
done

echo "wait" >> ${tmp}/bconsole_backup_jobs
echo "messages" >> ${tmp}/bconsole_backup_jobs

# start all the jobs again
bin/bconsole < ${tmp}/bconsole_backup_jobs

#testing for releasing when device is on autoselect=no
cat <<END_OF_DATA > "${tmp}/bconcmds"
@$out ${runner_tmp}/log-label-release-autoselect-no.out
setdevice storage=Tape-0  device=${tapedevices[0]} autoselect=no
release storage=Tape-0 drive=0
messages
quit
END_OF_DATA

run_bconsole

#check the that the labeling went through
if ! grep "Slot 8 successfully created." "${runner_tmp}"/log-label-release-autoselect-no.out \
  && grep "3999 Device \"autochanger-0\" not found or could not be opened." "${runner_tmp}"/log-label-release-autoselect-no.out; then
  echo "Labeling of a device with autoselect=no was not successful. Check ${runner_tmp}/log-label-release-autoselect-no.out" >&2
  estat=1
fi

#check that release went through
if ! grep "3921 Device \"\"${tapedevices[0]}\" (.*)\" already released." "${runner_tmp}"/log-label-release-autoselect-no.out \
  && grep "3999 Device \"autochanger-0\" not found or could not be opened." "${runner_tmp}"/log-label-release-autoselect-no.out; then
  echo "Releasing a device with autoselct=no was not successful. Check ${runner_tmp}/log-label-release-autoselect-no.out" >&2
  estat=1
fi

#check that the tapedrive works normally again after the manipulations
if ! grep "Using .* \"${tapedevices[0]}" "${runner_tmp}"/log-second-backups.out; then
  echo "A device that was on autoselect=no and then back to autoselect=yes was not used. Check ${runner_tmp}/log-second-backups.out" >&2
  estat=1
fi

check_for_zombie_jobs storage=Tape-0

release_all_devices

end_test
exit 0
