#!/bin/bash

###
### borg_backup.sh
###
### Usage:
###   borg_backup.sh [-f]
###
### Options:
###   -f          Force an update, even if one was already made today.
###   -h          Print this help message and quit.
###


print_help() {
  awk -F'### ' '/^###/ { print $2 }' "$0"
}

cache_file="$HOME/.cache/borg_backup_hook_last_executed"
stat_cache_file() {
  # We only want this file to be executed at most once per day, so we stat a cache
  # file before running the rest of the code
  if [ -f "$cache_file" ]; then
    cache_stat=$(stat -c %y "$cache_file" | cut -d' ' -f1)
    today=$(date +%Y-%m-%d)
    if [ "$cache_stat" = "$today" ]; then
      echo "The borg backup was already executed today" && exit 0
    fi
  fi
}

if [ "$1" = '-h' ]; then
  print_help && exit 1
fi

if [ ! "$UID" -eq 0 ]; then
  echo "You have to run this as root!" && exit 1
fi

[ "$1" = '-f' ] || stat_cache_file

touch "$cache_file"

# Setting this so the repo does not need to be given on the command line:
BORG_REPO=ssh://"$BORG_REPO":22/~/"$(hostname)".borg
export BORG_REPO

BORG_PASSPHRASE="$BORG_PASSPHRASE"
export BORG_PASSPHRASE

# some helpers and error handling:
info() { printf "\n%s %s\n\n" "$(date)" "$*" >&2; }
trap 'echo $(date) Backup interrupted >&2; exit 2' INT TERM

info "Starting backup"

# Backup the most important directories into an archive named after
# the machine this script is currently running on:
borg create                     	       \
  --verbose                     	       \
  --filter AME                  	       \
  --list                        	       \
  --stats                       	       \
  --show-rc                     	       \
  --compression lz4             	       \
  --exclude-caches              	       \
  --exclude '/home/*/.*/*'  	 	         \
  --exclude '/home/*/.*'                 \
  --exclude-from <(echo "$BORG_EXCLUDES")\
  --exclude '/var/cache/*'      	       \
  --exclude '/var/log/*'      	 	       \
  --exclude '/var/tmp/*'        	       \
                                	       \
  ::'{hostname}-{now}'          	       \
  /etc                          	       \
  /home                         	       \
  /root                         	       \
  /var                          	       \

backup_exit=$?

info "Pruning repository"

# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-' prefix is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:
borg prune                               \
  --list                                 \
  --prefix '{hostname}-'                 \
  --show-rc                              \
  --keep-daily    7                      \
  --keep-weekly   4                      \
  --keep-monthly  6                      \

prune_exit=$?

# Use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))

if [ ${global_exit} -eq 0 ]; then
  info "Backup and Prune finished succesfully"
elif [ ${global_exit} -eq 1 ]; then
  info "Backup and/or Prune finished with warnings"
else
  info "Backup and/or Prune finished with errors"
fi

exit ${global_exit}