#!/bin/bash

CONF=/etc/btrbk/btrbk-cron.conf
LOCKFILE=/run/btrbk/btrbk.lock
LOGFILE=$(mktemp)
trap 'rm -f -- "${LOGFILE}"' EXIT

# check for superpowers
if [[ "${EUID}" -ne 0 ]] ; then
  echo "Please run me as root"
  exit 1
fi

echo "---" | tee -a "${LOGFILE}"
echo "Start btrbk-cron: $(date||true)" | tee -a "${LOGFILE}"

if [[ ! -f "${CONF}" ]] ; then
  echo "Warning: Can't read config file (${CONF}), healthchecks disabled." | tee -a "${LOGFILE}"
else
  # shellcheck disable=SC1090,SC1091
  source "${CONF}"
fi

HEALTHCHECK_URL=${HEALTHCHECK_URL:-http://127.0.0.1}
HEALTHCHECK_ENABLE=${HEALTHCHECK_ENABLE:-false}
FAIL_IF_TARGET_UNREACHABLE=${FAIL_IF_TARGET_UNREACHABLE:-true}
IGNORE_TARGET_UNREACHABLE=${IGNORE_TARGET_UNREACHABLE:-false}
CURLOPTS=(-fsS -m 10 --retry 5)

if [[ ! -d /run/btrbk ]] ; then
  echo "Warning: Creating missing directory: /run/btrbk " | tee -a "${LOGFILE}"
  mkdir -p /run/btrbk
fi

if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
  echo "Info: Healthchecks enabled with URL: ${HEALTHCHECK_URL}"
else
  echo "Info: Healthchecks disabled"
fi

# lockfile check
if [[ -f "${LOCKFILE}" ]] ; then
  # check if stale lockfile
  if [[ $(pgrep --exact --count btrbk || true) -eq 0 ]] ; then
    echo "Removing stale lock file: ${LOCKFILE}"
    rm "${LOCKFILE}"
  else
    # another instance is really running, we exit
    echo "Another instance is still running" | tee -a "${LOGFILE}"
    if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
      curl "${CURLOPTS[@]}" --data-binary "@${LOGFILE}" "${HEALTHCHECK_URL}/log"
    fi
    rm -f -- "${LOGFILE}"
    exit 0
  fi
fi

HOST=$(grep -E '^[\ \t]*target[\ \t]+send-receive' /etc/btrbk/btrbk.conf)
# TODO: support for dashes in hostname and IPv6 ("[2001:db8::7]")
HOST=$(echo "${HOST}" | sed -r 's/.*ssh:\/\/([0-9\.a-zA-Z]+).*/\1/g' )

IDENTITYFILE=$(grep -E '^[\ \t]*ssh_identity[\ \t].*' /etc/btrbk/btrbk.conf )
IDENTITYFILE=$(echo "${IDENTITYFILE}" | sed -r 's/.*ssh_identity[\ \t]+//g')

SSHUSER=$(grep -E '^[\ \t]*ssh_user[\ \t].*' /etc/btrbk/btrbk.conf )
SSHUSER=$(echo "${SSHUSER}" | sed -r 's/.*ssh_user[\ \t]+//g')

SSH_OK=$(ssh -i "${IDENTITYFILE}" "${SSHUSER}@${HOST}" "which btrfs")

if [[ "${IGNORE_TARGET_UNREACHABLE}" = "false" ]] ; then
  if [[ "${SSH_OK}" = "" ]] ; then
    echo "Warning: exiting because of backup destination unreachable" | tee -a "${LOGFILE}"
    if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
      curl "${CURLOPTS[@]}" --data-binary "@${LOGFILE}" "${HEALTHCHECK_URL}/log"
    fi
    rm -f -- "${LOGFILE}"
    if [[ "${FAIL_IF_TARGET_UNREACHABLE}" = "true" ]] ; then
      exit 1
    else
      exit 0
    fi
  fi
fi

echo "Start backup: $(date||true)" | tee -a "${LOGFILE}"
if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
  curl "${CURLOPTS[@]}" "${HEALTHCHECK_URL}/start"
fi
echo
echo "healthcheck notified! (start)" | tee -a "${LOGFILE}"
(nice -n 19 /usr/bin/ionice -c idle /usr/bin/btrbk -v --progress run 2>&1 || true) | tee -a "${LOGFILE}" 2>&1
ret=$?
if [[ "${ret}" -eq "0" ]]; then
  if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
    curl "${CURLOPTS[@]}" "${HEALTHCHECK_URL}" 
  fi
  echo
  echo "healthcheck notified! (ok)" | tee -a "${LOGFILE}"
else 
  if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
    curl "${CURLOPTS[@]}" "${HEALTHCHECK_URL}/fail"
  fi
  echo
  echo "healthcheck notified! (fail)" | tee -a "${LOGFILE}"
fi
echo "starting cleanup" | tee -a "${LOGFILE}"
(nice -n 19 /usr/bin/ionice -c idle /usr/bin/btrbk clean >> "${LOGFILE}" ; ) 2>&1

echo "backup finished, sending logs" | tee -a "${LOGFILE}"
if [[ "${HEALTHCHECK_ENABLE}" = "true" ]] ; then
  curl "${CURLOPTS[@]}" --data-binary "@${LOGFILE}" "${HEALTHCHECK_URL}/log"
fi
echo
rm -f -- "${LOGFILE}"
echo "backup finished"
