#!/usr/bin/env bash
# We don't stop the script on errors cause we want to backup all data we could backed up
#set -eu

borg_id=$1
errors=""
current_date=$(date +"%y%m%d_%H%M")
log_file="/var/log/${borg_id}/${current_date}.log"
err_file="/var/log/${borg_id}/${current_date}.err"
mkdir -p "/var/log/${borg_id}"
if [ -z "$borg_id" ]; then
    echo "This script expects a borg app id as first argument" >&2
    exit 1
fi

filter_hooks() {
    sudo ls /usr/share/yunohost/hooks/backup/ /etc/yunohost/hooks.d/backup/ | grep "\-$1_" | cut -d"-" -f2 | uniq 2>> "$err_file"
}

fail_if_partially_failed() {
    grep Skipped|Error
}
sudo yunohost app setting "${borg_id}" last_run -v "${current_date}"
sudo yunohost app setting "${borg_id}" state -v "ongoing"

# Backup system part conf
conf=$(sudo yunohost app setting "${borg_id}" conf)
if [[ "$conf" = "1" ]]; then
    if ! sudo yunohost backup create -n auto_conf --method "${borg_id}_app" --system $(filter_hooks conf) 2>> "$err_file" >> "$log_file" ; then
        errors+="\nThe backup miserably failed to backup system configurations."
    fi
fi

# Backup system data
data=$(sudo yunohost app setting "${borg_id}" data)
if [[ "$data" = "1" ]]; then
    if ! sudo yunohost backup create -n auto_data --method "${borg_id}_app" --system $(filter_hooks data) 2>> "$err_file" >> "$log_file" ; then
        errors+="\nThe backup miserably failed to backup system data."
    fi
fi

# Backup all apps independently
apps=$(sudo yunohost app setting "${borg_id}" apps | tr -d ' ')
for application in $(sudo ls /etc/yunohost/apps/); do

    if ( [[ "$apps" =~ ^exclude: ]] && grep -wq "$application" <<< "$apps" ) ||
       ( [[ "$apps" != "all" ]] && [[ ! "$apps" =~ ^exclude: ]]  && ! grep -wq "$application" <<< "$apps" );
    then
        continue
    fi

    if sudo test ! -f "/etc/yunohost/apps/$application/scripts/backup" ; then
        errors+="\nWarning: The application $application has no backup script. This app won't be backed up."
        continue
    fi

    if ! sudo yunohost backup create -n "auto_$application" --method "${borg_id}_app" --apps "$application" 2>> "$err_file" >> "$log_file" ; then
        errors+="\nThe backup miserably failed to backup $application application."
    fi
done

#=========================================================
# SEND MAIL TO NOTIFY ABOUT SUCCEEDED OR FAILED OPERATIONS
#=========================================================

partial_errors="$(cat "$log_file" | grep -E "Error|Skipped")"
if [ -n "$partial_errors" ]; then
    errors+="\nSome backup partially failed:\n$partial_errors"
fi

# Send mail on backup (partially) failed
domain=$(hostname)
repository="$(sudo yunohost app setting "${borg_id}" repository)"
mailalert="$(sudo yunohost app setting "${borg_id}" mailalert)"
if [[ -n "$errors" ]]; then
    sudo yunohost app setting "${borg_id}" state -v "failed"
else
    sudo yunohost app setting "${borg_id}" state -v "successful"
fi

if [[ -n "$errors" && $mailalert != "never" ]]; then
    cat <(echo -e "$errors\n\n\n") "$log_file" "$err_file" | mail -a "Content-Type: text/plain; charset=UTF-8" -s "[borg] Backup failed from $domain onto $repository" root
    exit 1
elif [ "$mailalert" == "always" ]; then
    cat "$log_file" | mail -a "Content-Type: text/plain; charset=UTF-8" -s "[borg] Backup succeeded from $domain onto $repository" root
    exit 0
fi
