#!/bin/bash

#   BAREOS® - Backup Archiving REcovery Open Sourced
#
#   Copyright (C) 2026-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.

set -e
set -o pipefail
set -u

#
# verify that prune keeps a full job while an incremental still depends on it
# and only allows pruning after the dependent job is gone
#

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

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

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

start_test

history_job_name=history-backup-bareos-fd
history_full_volume=HistoryFull001
history_incremental_volume=HistoryIncremental001

cat <<END_OF_DATA >"$tmp/bconcmds"
@$out ${log_home}/backup.out
label volume=${history_full_volume} storage=File pool=HistoryFull
label volume=${history_incremental_volume} storage=File pool=HistoryIncremental
run job=${history_job_name} Level=Full yes
wait
run job=${history_job_name} Level=Incremental yes
wait
messages
quit
END_OF_DATA

run_bconsole

check_log "${log_home}/backup.out"

job_rows=$(
  psql -d "${db_name}" -At -F '|' \
    -c "SELECT JobId, JobStatus, Level, COALESCE(BaseId, 0), COALESCE(ContentId, 0) FROM Job WHERE Name='${history_job_name}' ORDER BY JobId"
)
job_rows="$(printf '%s' "${job_rows}" | tr -d '\r')"

full_row="$(sed -n '1p' <<<"${job_rows}")"
incremental_row="$(sed -n '2p' <<<"${job_rows}")"

IFS='|' read -r full_jobid full_status full_level full_baseid full_contentid <<<"${full_row}"
IFS='|' read -r incremental_jobid incremental_status incremental_level incremental_baseid incremental_contentid <<<"${incremental_row}"

if [ -z "${full_jobid}" ] || [ -z "${incremental_jobid}" ]; then
  set_error "Expected two history jobs, got: ${job_rows}"
  exit 1
fi

if [ "${full_status}" != "T" ] || [ "${full_level}" != "F" ] \
  || [ "${full_baseid}" != "0" ] || [ "${full_contentid}" != "${full_jobid}" ]; then
  set_error "Unexpected full lineage row: ${full_row}"
  exit 1
fi

if [ "${incremental_status}" != "T" ] || [ "${incremental_level}" != "I" ] \
  || [ "${incremental_baseid}" != "${full_contentid}" ] \
  || [ "${incremental_contentid}" != "${incremental_jobid}" ]; then
  set_error "Unexpected incremental lineage row: ${incremental_row}"
  exit 1
fi

sleep 2

cat <<END_OF_DATA >"$tmp/bconcmds"
@$out ${log_home}/prune-protected.out
update volume=${history_full_volume} volstatus=Used
prune volume=${history_full_volume} yes
wait
quit
END_OF_DATA

run_bconsole

expect_grep "Pruning volume ${history_full_volume}: 0 Jobs have expired and can be pruned." \
  "${log_home}/prune-protected.out" \
  "Expected protected full volume to keep all jobs"

expect_grep "Volume \"${history_full_volume}\" still contains jobs after pruning." \
  "${log_home}/prune-protected.out" \
  "Expected protected full volume to still contain jobs"

full_job_count="$(
  psql -d "${db_name}" -At -c "SELECT COUNT(*) FROM Job WHERE JobId=${full_jobid}" \
    | tr -d '\r'
)"
if [ "${full_job_count}" != "1" ]; then
  set_error "Full job ${full_jobid} should still exist after protected prune, count=${full_job_count}"
  exit 1
fi

cat <<END_OF_DATA >"$tmp/bconcmds"
@$out ${log_home}/prune-dependent.out
prune jobs pool=HistoryIncremental yes
wait
quit
END_OF_DATA

run_bconsole

expect_grep "Purging the following 1 JobIds: ${incremental_jobid}" \
  "${log_home}/prune-dependent.out" \
  "Expected dependent incremental job to be pruned"

expect_grep "Pruned 1 Job for client bareos-fd from catalog." \
  "${log_home}/prune-dependent.out" \
  "Expected exactly one dependent job to be pruned"

incremental_job_count="$(
  psql -d "${db_name}" -At -c "SELECT COUNT(*) FROM Job WHERE JobId=${incremental_jobid}" \
    | tr -d '\r'
)"
if [ "${incremental_job_count}" != "0" ]; then
  set_error "Incremental job ${incremental_jobid} should be pruned, count=${incremental_job_count}"
  exit 1
fi

cat <<END_OF_DATA >"$tmp/bconcmds"
@$out ${log_home}/prune-released.out
update volume=${history_full_volume} volstatus=Used
prune volume=${history_full_volume} yes
wait
quit
END_OF_DATA

run_bconsole

expect_grep "Pruning volume ${history_full_volume}: 1 Jobs have expired and can be pruned." \
  "${log_home}/prune-released.out" \
  "Expected released full volume to prune one job"

expect_grep "Purging the following 1 JobIds: ${full_jobid}" \
  "${log_home}/prune-released.out" \
  "Expected released full job to be pruned"

expect_grep "Volume \"${history_full_volume}\" contains no jobs after pruning." \
  "${log_home}/prune-released.out" \
  "Expected released full volume to be empty after pruning"

full_job_count="$(
  psql -d "${db_name}" -At -c "SELECT COUNT(*) FROM Job WHERE JobId=${full_jobid}" \
    | tr -d '\r'
)"
if [ "${full_job_count}" != "0" ]; then
  set_error "Full job ${full_jobid} should be pruned after dependent removal, count=${full_job_count}"
  exit 1
fi

end_test
