#!/bin/bash
#
# MCU DB compression and integrity check, available disk space check and remote backup tool v1.0.3
# Created by Enrico Buttignol (ebuttignol@messana.tech) on Jun 14, 2021
# Copyright by Messana Hydronic Technologies

# Changelog:

# Mmm dd, yyyy - Name Surname (email@server.com) - description

# Sep 16, 2022 - Enrico Buttignol (ebuttignol@messana.tech) - Added header and code optimization
# Sep 26, 2022 - Enrico Buttignol (ebuttignol@messana.tech) - Bug fixes
# Dec 2, 2022 - Enrico Buttignol (ebuttignol@messana.tech) - Updated bash colors and code optimization
# May 3, 2023 - Massimiliano Bortolus (mbortolus@messana.tech) - Added startup environment
# Apr 19, 2024 - Enrico Buttignol (ebuttignol@messana.tech) - Updated rsync directories
# Aug 29, 2025 - Enrico Buttignol - Removed rsync -p/-o/-g, switched from SendGrid to Brevo API

# sudo ./remote-backup

# Colors
COLOR_SECTION='\033[0;36m'
COLOR_INFO='\033[0;96m'
COLOR_EXECUTED='\033[0;32m'
COLOR_WARNING='\033[33m'
COLOR_ERR='\033[0;31m'
NOCOLOR='\033[0m'

# Values
VPN=$( { ip a s tun0 | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'; } 2> /dev/null )
IS_PRODUCTION_ENV=$(/usr/share/messana/scripts/mht-get-mcu-environment.sh $VPN)
if [ "$IS_PRODUCTION_ENV" = true ]; then
    ENVIRONMENT="Final User"
else
    ENVIRONMENT="Development/Debug"
fi
BOARD_VENDOR=$(cat /sys/class/dmi/id/board_vendor)
if [ "$BOARD_VENDOR" = "NU691" ]; then
    SYSTEM_HARDWARE="Jetway"
else
    SYSTEM_HARDWARE="MSC Technologies"
fi
OS_VERSION=$(cat /etc/*release | grep -E ^VERSION_ID | cut -d'"' -f2)
REDISKEY=$(awk '/^requirepass /{print $2}' /etc/redis/redis.conf | uniq)
REDIS_VERSION=$(redis-server -v | grep -Po '(?<=Redis server v=)([\d]*.[\d]*.[\d]*)' | awk -F'[^0-9]+' '{ print $1 }')
OLD_REDIS_VERSION=3
if [ "$REDIS_VERSION" -gt "$OLD_REDIS_VERSION" ]; then
    REDIS_WARNING_PASSWORD="--no-auth-warning"
else
    REDIS_WARNING_PASSWORD=""
fi
CODE=$(redis-cli -a "$REDISKEY" $REDIS_WARNING_PASSWORD GET CFG_MCU_000_Code)
MCU_NAME=$(redis-cli -a "$REDISKEY" $REDIS_WARNING_PASSWORD GET CFG_MCU_000_Name)
if [ "$IS_PRODUCTION_ENV" = true ]; then
    SYSTEM=$MCU_NAME
else
    SYSTEM="MHT Development/Debug System / $MCU_NAME"
fi

HB_CONFIG_FILE='/var/homebridge/config.json'
DB_DEST='/usr/share/logic/db/'
COUNT_DB_FILES=$(find ${DB_DEST} -name '*.db' 2>/dev/null | wc -l)
DISK_SIZE=$(df -h / | awk '{ print $2 }' | tail -n 1)
USED_DISK_SPACE_M=$(df -h / | awk '{ print $4 }' | tail -n 1)
USED_DISK_SPACE_P=$(df / | awk '{ print $5 }' | tail -n 1 | cut -d% -f 1)
FREE_DISK_SPACE=$((100 - USED_DISK_SPACE_P))
MAX_ALLOWED_DISK_SPACE=97
BIGGER_DB_FILE=$(du -m ${DB_DEST}*.db | sort -n -r | head -n 1 | cut -f -1)
MAX_DB_SIZE_MSC=150
MAX_DB_SIZE=500

# Email setup with Brevo
BREVO_API_KEY="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"
EMAIL_TO="support@messana.tech"
FROM_EMAIL="no-reply@messana.tech"
FROM_NAME="Messana Alert"
ROW_SEPARATOR="---------------------------------------"
BOARD_VENDOR=$(cat /sys/class/dmi/id/board_vendor)
SYSTEM_ENVIRONMENT_TEXT="System Environment: $ENVIRONMENT"
SYSTEM_HARDWARE_TEXT="System HW: $SYSTEM_HARDWARE"
SYSTEM_OS_TEXT="System OS: Debian $OS_VERSION"

send_brevo_email() {
    SUBJECT="$1"
    BODY="$2"
    curl -X POST "https://api.brevo.com/v3/smtp/email" \
        -H "accept: application/json" \
        -H "api-key: $BREVO_API_KEY" \
        -H "content-type: application/json" \
        -d "{
          \"sender\": {\"name\": \"$FROM_NAME\", \"email\": \"$FROM_EMAIL\"},
          \"to\": [{\"email\": \"$EMAIL_TO\"}],
          \"subject\": \"$SUBJECT\",
          \"textContent\": \"$BODY\"
        }"
}

DB_SUBJECT="[$CODE] $SYSTEM - Alert status, the DB size exceeds the limit allowed."
DB_MESSAGE="Event notification from system [$CODE] $SYSTEM\n\nThe DB file size of system exceeds the limit allowed.\n\n$ROW_SEPARATOR\nSystem ID: $CODE\n$ROW_SEPARATOR\nSystem VPN IP: $VPN\n$ROW_SEPARATOR\n$SYSTEM_ENVIRONMENT_TEXT\n$ROW_SEPARATOR\n$SYSTEM_HARDWARE_TEXT\n$ROW_SEPARATOR\n$SYSTEM_OS_TEXT\n$ROW_SEPARATOR\nThe DB file size is: ${BIGGER_DB_FILE}M\n$ROW_SEPARATOR\nSystem disk size: $DISK_SIZE\n$ROW_SEPARATOR\nTotal disk space available: $USED_DISK_SPACE_M ($FREE_DISK_SPACE%)\n$ROW_SEPARATOR\n"

DISK_SPACE_SUBJECT="[$CODE] $SYSTEM - Alert status, the disk space is near full."
DISK_SPACE_MESSAGE="Event notification from system [$CODE] $SYSTEM\n\nThe system disk is running low on free space.\n\n$ROW_SEPARATOR\nSystem ID: $CODE\n$ROW_SEPARATOR\nSystem VPN IP: $VPN\n$ROW_SEPARATOR\n$SYSTEM_ENVIRONMENT_TEXT\n$ROW_SEPARATOR\n$SYSTEM_HARDWARE_TEXT\n$ROW_SEPARATOR\n$SYSTEM_OS_TEXT\n$ROW_SEPARATOR\nSystem disk size: $DISK_SIZE\n$ROW_SEPARATOR\nTotal disk space available: $USED_DISK_SPACE_M ($FREE_DISK_SPACE%)\n$ROW_SEPARATOR\n"

CORRUPTED_GZIP_SUBJECT="[$CODE] $SYSTEM - Alert status, there are corrupted gzipped DB files"
CORRUPTED_GZIP_MESSAGE="Event notification from system [$CODE] $SYSTEM\n\nThere are corrupted gziped DB files, please check the system disk and the filesystem integrity."

printf "\n"
printf "%s""${COLOR_SECTION}[»»»] MCU REMOTE BACKUP STARTED [«««]${NOCOLOR}"
printf "\n"

cd "$DB_DEST" || exit

if [ "$COUNT_DB_FILES" != 0  ]; then
    if [ "$BOARD_VENDOR" == "NU691" ]; then
        if [ "$BIGGER_DB_FILE" -ge "$MAX_DB_SIZE" ]; then
            send_brevo_email "$DB_SUBJECT" "$DB_MESSAGE"
        fi
    else
        if [ "$BIGGER_DB_FILE" -ge "$MAX_DB_SIZE_MSC" ]; then
            send_brevo_email "$DB_SUBJECT" "$DB_MESSAGE"
        fi
    fi

    if [ "$USED_DISK_SPACE_P" -ge "$MAX_ALLOWED_DISK_SPACE" ]; then
        send_brevo_email "$DISK_SPACE_SUBJECT" "$DISK_SPACE_MESSAGE"
    else
        if [ "$IS_PRODUCTION_ENV" = true ]; then
            printf "%s""${COLOR_INFO}[i]${NOCOLOR} Production MCU, starting system backup.\n"
            gzip -kf9 ./*.db

            if gzip -t ./*.gz; then

                # Remote backup (senza -p, con --no-o --no-g)
                rsync -rtz --no-o --no-g --password-file=/etc/rsync.secrets /usr/share/logic/statistics cm-remote@radiantcooling.com::"${CODE}"/
                rsync -rtz --no-o --no-g --password-file=/etc/rsync.secrets /usr/share/logic/db/*.gz cm-remote@radiantcooling.com::"${CODE}"/db/
                rsync -rtz --no-o --no-g --delete --password-file=/etc/rsync.secrets /var/lib/redis cm-remote@radiantcooling.com::"${CODE}"/
                rsync -rtz --no-o --no-g --password-file=/etc/rsync.secrets /etc/network/interfaces.d cm-remote@radiantcooling.com::"${CODE}"/

                if test -f "$HB_CONFIG_FILE"; then
                    rsync -rtz --no-o --no-g --delete --password-file=/etc/rsync.secrets /var/homebridge/config.json cm-remote@radiantcooling.com::"${CODE}"/homebridge/
                fi

                printf "%s""${COLOR_EXECUTED}[+]${NOCOLOR} System backup completed.\n"
                rm ./*.gz
            else
                send_brevo_email "$CORRUPTED_GZIP_SUBJECT" "$CORRUPTED_GZIP_MESSAGE"
                printf "%s""${COLOR_ERR}[×]${NOCOLOR} The database gzip archive is corrupted, backup aborted.\n"
            fi
        fi
    fi
else
    if [ "$IS_PRODUCTION_ENV" = true ]; then
        rsync -rtz --no-o --no-g --password-file=/etc/rsync.secrets /usr/share/logic/statistics cm-remote@radiantcooling.com::"${CODE}"/
        rsync -rtz --no-o --no-g --password-file=/etc/rsync.secrets /usr/share/logic/db cm-remote@radiantcooling.com::"${CODE}"/
        rsync -rtz --no-o --no-g --delete --password-file=/etc/rsync.secrets /var/lib/redis cm-remote@radiantcooling.com::"${CODE}"/
        rsync -rtz --no-o --no-g --password-file=/etc/rsync.secrets /etc/network/interfaces.d cm-remote@radiantcooling.com::"${CODE}"/

        if test -f "$HB_CONFIG_FILE"; then
            rsync -rtz --no-o --no-g --delete --password-file=/etc/rsync.secrets /var/homebridge/config.json cm-remote@radiantcooling.com::"${CODE}"/homebridge/
        fi

        printf "%s""${COLOR_SECTION}[»»»] FIRST SYSTEM SETUP COMPLETED [«««]${NOCOLOR}\n"
    fi
fi

if [ "$IS_PRODUCTION_ENV" = false ]; then
  printf "${COLOR_INFO}[i]${NOCOLOR} This is a Debug/Dev system, no backup required."
fi

exit 0
