#!/bin/sh
#
#   Backup - Create a timestamped backup of the game.
#
#   Includes the SQLite database, configuration, and text files.
#   Safe to run while the server is live. Uses SQLite's .backup
#   command which handles WAL correctly for the database snapshot.
#
PATH=/bin:/usr/bin:/usr/local/bin:.; export PATH
#
. mux.config
#
DBDATE=$(date +%m%d-%H%M%S)
BACKUP_TAR=$GAMENAME.$DBDATE.tar.gz
BACKUP_TAR_TMP=$BACKUP_TAR.tmp.$$

cleanup_tmp()
{
    rm -f "$BACKUP_TMP" "$BACKUP_TAR_TMP"
}
trap cleanup_tmp EXIT HUP INT TERM

if ! command -v sqlite3 >/dev/null 2>&1; then
    echo "sqlite3 not found in PATH."
    exit 1
fi

if ! command -v tar >/dev/null 2>&1; then
    echo "tar not found in PATH."
    exit 1
fi

if ! command -v gzip >/dev/null 2>&1; then
    echo "gzip not found in PATH."
    exit 1
fi

if [ -r "$DATA/$GAMENAME.sqlite" ]; then
    SQLITE_DB=$DATA/$GAMENAME.sqlite
else
    echo "No SQLite database found at $DATA/$GAMENAME.sqlite"
    exit 1
fi

BACKUP_DB=$DATA/$GAMENAME.$DBDATE.sqlite
BACKUP_TMP=$BACKUP_DB.tmp.$$

if [ -e "$BACKUP_TAR" ]; then
    echo "Backup target already exists: $BACKUP_TAR"
    exit 1
fi

# Phase 1: Rigorous SQLite database backup via .backup API.
#
echo "Backing up $SQLITE_DB..."
if ! sqlite3 "$SQLITE_DB" ".backup '$BACKUP_TMP'"; then
    echo "Backup failed during sqlite3 .backup."
    rm -f "$BACKUP_TMP"
    exit 1
fi

if ! mv -f "$BACKUP_TMP" "$BACKUP_DB"; then
    echo "Backup failed while finalizing database snapshot."
    rm -f "$BACKUP_TMP"
    exit 1
fi

if [ ! -r "$BACKUP_DB" ]; then
    echo "Backup failed."
    exit 1
fi

# Phase 2: Bundle database snapshot with configuration and text files.
#
if [ ! -r "mux.config" ]; then
    echo "Required config file missing: mux.config"
    echo "Database snapshot preserved at: $BACKUP_DB"
    exit 1
fi

if [ ! -r "$GAMENAME.conf" ]; then
    echo "Required config file missing: $GAMENAME.conf"
    echo "Database snapshot preserved at: $BACKUP_DB"
    exit 1
fi

# Game-specific text files to back up.  Distribution help files
# (help.txt, wizhelp.txt, connect_help.txt) are deliberately excluded
# — they ship with TinyMUX and are restored by reinstalling.
#
TEXT_FILES="\
 $TEXT/badsite.txt\
 $TEXT/connect.txt\
 $TEXT/create_reg.txt\
 $TEXT/down.txt\
 $TEXT/full.txt\
 $TEXT/guest.txt\
 $TEXT/motd.txt\
 $TEXT/news.txt\
 $TEXT/newuser.txt\
 $TEXT/plushelp.txt\
 $TEXT/quit.txt\
 $TEXT/register.txt\
 $TEXT/staffhelp.txt\
 $TEXT/wizmotd.txt\
 $TEXT/wiznews.txt"

set -- "$BACKUP_DB" "mux.config" "$GAMENAME.conf"
TEXT_COUNT=0
for f in $TEXT_FILES; do
    if [ -r "$f" ]; then
        set -- "$@" "$f"
        TEXT_COUNT=$((TEXT_COUNT + 1))
    fi
done

if [ "$TEXT_COUNT" -eq 0 ]; then
    echo "Warning: no readable text files found under $TEXT"
fi

if ! tar cf - "$@" | gzip -9 > "$BACKUP_TAR_TMP"; then
    echo "Backup failed during archive creation."
    echo "Database snapshot preserved at: $BACKUP_DB"
    exit 1
fi

if [ ! -s "$BACKUP_TAR_TMP" ]; then
    echo "Backup failed: archive is empty."
    echo "Database snapshot preserved at: $BACKUP_DB"
    exit 1
fi

if ! mv -f "$BACKUP_TAR_TMP" "$BACKUP_TAR"; then
    echo "Backup failed while finalizing archive."
    echo "Database snapshot preserved at: $BACKUP_DB"
    exit 1
fi

if ! tar tzf "$BACKUP_TAR" >/dev/null 2>&1; then
    echo "Backup failed: archive verification failed."
    echo "Database snapshot preserved at: $BACKUP_DB"
    exit 1
fi

rm -f "$BACKUP_DB"
echo "Backup complete: $BACKUP_TAR"
