#!/bin/bash
# TT#66223 check and clean old backups in /var/backup or /ngcp-data/backup/ngcp-upgrade

set -e
set -u
set -o pipefail

die() {
  local message="$*"

  echo "ERROR: ${message}" >&2
  exit 1
}

request_confirmation() {
  if [[ "${FORCE_UPGRADE}" = "true" ]] ; then
    echo "Forcing as requested via environment variable FORCE_UPGRADE."
    return
  fi

  while true; do
    echo -n "Should we perform the cleaning? (yes/no): "
    read -r answer
    case "${answer,,}" in
      yes)
        echo "Performing as requested."
        return 0
        ;;
      no)
        echo "Cancelled as requested."
        return 1
        ;;
      * )
        echo "Please answer 'yes' or 'no'."
        ;;
    esac
    unset answer
  done
}

fatal_missing_var() {
  local var_name="$1"
  if [[ ! -v "${var_name}" ]] ; then
    die "Missing mandatory environment variable '\$${var_name}', exiting."
  fi

  local var_value="${!var_name}"
  if [[ -z "${var_value}" ]] ; then
    die "Empty mandatory environment variable '\$${var_name}', exiting."
  fi
}

fatal_missing_var FORCE_UPGRADE
fatal_missing_var BACKUP
fatal_missing_var OLD_VERSION


# pre-conditions, exit if dirs don't exist, get dirs to look at, etc
if [[ ! "${BACKUP}" =~ /ngcp-data/backup/ngcp-upgrade/ngcp-.* ]] && [[ ! "${BACKUP}" =~ /var/backup/ngcp-.* ]]; then
  die "\$BACKUP env var contains a string that we are not prepared for ('${BACKUP}'), aborting"
fi

dirs_to_check=()
BACKUP_BASE_DIR="/ngcp-data/backup/ngcp-upgrade"

if df |& grep /ngcp-data &>/dev/null && [[ -d "${BACKUP_BASE_DIR}" ]] ; then
  echo "INFO: adding ${BACKUP_BASE_DIR} to dirs to consider"
  dirs_to_check+=( "${BACKUP_BASE_DIR}" )
fi

if [[ -e /var/backup ]] && ! (df /var/backup |& grep /ngcp-data &>/dev/null); then
  echo "INFO: adding /var/backup to dirs to consider"
  dirs_to_check+=( "/var/backup" )
fi

if [[ "${#dirs_to_check[@]}" -eq 0 ]] ; then
  echo "INFO: no directories to check (neither /var/backup nor ${BACKUP_BASE_DIR})"
  exit 0
fi


# find candidates to remove
tmpfile=$(mktemp)
if ! find "${dirs_to_check[@]}" -maxdepth 1 -type d -regex '.*/ngcp-\(mr.*\|[23]\..*\|trunk\)' &> "${tmpfile}" ; then
  die "Problem running 'find' on dir(s), check '${tmpfile}': " "${dirs_to_check[@]}"
fi

backups_to_remove_initial=()
while IFS= read -r line ; do
  backups_to_remove_initial+=("${line}")
done < <(sort --version-sort "${tmpfile}")

rm -f "${tmpfile}"

backups_to_remove=()
for d in "${backups_to_remove_initial[@]}"; do
  d_basename="$(basename "${d}")"
  d_version="${d_basename/ngcp-/}"
  if dpkg --force-bad-version --compare-versions "${d_version}" ge "${OLD_VERSION}" &>/dev/null ; then
    echo "INFO: ignoring directory, seems to be from same or higher version: ${d}"
    continue
  fi

  backups_to_remove+=( "${d}" )
done


if [[ "${#backups_to_remove[@]}" -eq 0 ]] ; then
  echo "INFO: no backups to remove"
else
  echo "INFO: We could remove the following old backup files/dirs:"
  du -shc "${backups_to_remove[@]}"

  if request_confirmation ; then
    echo "INFO: Removing the following files/dirs:"
    for d in "${backups_to_remove[@]}"; do
      echo " - ${d}"
      rm -fr "${d}"
    done
    echo "Done."
    echo
  fi
fi
