#!/usr/bin/env bash
# =============================================================================
# TapPass Manual / Cron Backup Script
#
# Usage:
#   bash backup.sh
#
# Credentials are read (in order of priority) from:
#   1. Environment variables: TAPPASS_DB_NAME, TAPPASS_DB_USER, TAPPASS_DB_PASS
#   2. /var/www/tappass/db.php  (parsed for $db_name, $db_user, $db_pass)
#
# Backups are written to /var/backups/tappass/
# Files older than 30 days are removed automatically.
#
# Exit codes:
#   0 — all backups succeeded
#   1 — one or more backups failed
# =============================================================================
set -euo pipefail

# ── Configuration ─────────────────────────────────────────────────────────────
BACKUP_DIR="${TAPPASS_BACKUP_DIR:-/var/backups/tappass}"
DB_PHP="/var/www/tappass/db.php"
MEDITAP_DIR="/var/www/meditap"
RETENTION_DAYS=30
DATE="$(date +%Y-%m-%d_%H-%M-%S)"
SUCCESS=true

# ── Colour helpers ─────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RESET='\033[0m'

log()     { echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
ok()      { echo -e "${GREEN}[OK]${RESET}    $*"; }
fail()    { echo -e "${RED}[FAIL]${RESET}  $*" >&2; }
notice()  { echo -e "${YELLOW}[NOTE]${RESET}  $*"; }

# ── Helper: extract a PHP variable value from db.php ─────────────────────────
# Handles:  $varname = 'value';  and  $varname = "value";
parse_php_var() {
    local varname="$1"
    local file="$2"
    # Strip comments, then grep for the variable, extract the quoted value
    grep -E "^\\\$${varname}\s*=" "${file}" 2>/dev/null \
        | head -1 \
        | sed -E "s/.*=\s*['\"]([^'\"]*)['\"].*/\1/"
}

# ── 1. Resolve TapPass DB credentials ─────────────────────────────────────────
log "Resolving TapPass database credentials..."

if [[ -n "${TAPPASS_DB_NAME:-}" && -n "${TAPPASS_DB_USER:-}" && -n "${TAPPASS_DB_PASS:-}" ]]; then
    notice "Using credentials from environment variables."
    TP_DB_NAME="${TAPPASS_DB_NAME}"
    TP_DB_USER="${TAPPASS_DB_USER}"
    TP_DB_PASS="${TAPPASS_DB_PASS}"
elif [[ -f "${DB_PHP}" ]]; then
    notice "Parsing credentials from ${DB_PHP}"
    TP_DB_NAME="$(parse_php_var 'db_name' "${DB_PHP}")"
    TP_DB_USER="$(parse_php_var 'db_user' "${DB_PHP}")"
    TP_DB_PASS="$(parse_php_var 'db_pass' "${DB_PHP}")"

    if [[ -z "${TP_DB_NAME}" || -z "${TP_DB_USER}" || -z "${TP_DB_PASS}" ]]; then
        fail "Could not parse db_name / db_user / db_pass from ${DB_PHP}."
        fail "Set TAPPASS_DB_NAME, TAPPASS_DB_USER, TAPPASS_DB_PASS env vars and retry."
        exit 1
    fi
else
    fail "No credentials found."
    fail "Either set TAPPASS_DB_NAME / TAPPASS_DB_USER / TAPPASS_DB_PASS environment variables,"
    fail "or ensure ${DB_PHP} exists and contains \$db_name, \$db_user, \$db_pass."
    exit 1
fi

log "  TapPass database : ${TP_DB_NAME}"
log "  TapPass user     : ${TP_DB_USER}"

# ── 2. Create backup directory ────────────────────────────────────────────────
mkdir -p "${BACKUP_DIR}"

# ── Helper: dump one database ─────────────────────────────────────────────────
dump_database() {
    local db_name="$1"
    local db_user="$2"
    local db_pass="$3"
    local out_file="${BACKUP_DIR}/${db_name}_${DATE}.sql.gz"

    log "Backing up '${db_name}'..."
    if mysqldump \
            --user="${db_user}" \
            --password="${db_pass}" \
            --single-transaction \
            --routines \
            --triggers \
            "${db_name}" \
        | gzip -9 > "${out_file}"; then
        local size
        size="$(du -sh "${out_file}" | cut -f1)"
        ok "  ${out_file}  (${size})"
        return 0
    else
        fail "  mysqldump failed for database '${db_name}'"
        rm -f "${out_file}" 2>/dev/null || true
        SUCCESS=false
        return 1
    fi
}

# ── 3. Back up TapPass database ───────────────────────────────────────────────
dump_database "${TP_DB_NAME}" "${TP_DB_USER}" "${TP_DB_PASS}" || true

# ── 4. Back up MediTap database (if /var/www/meditap exists) ─────────────────
if [[ -d "${MEDITAP_DIR}" ]]; then
    # Try to resolve MediTap credentials from environment first
    if [[ -n "${MEDITAP_DB_NAME:-}" && -n "${MEDITAP_DB_USER:-}" && -n "${MEDITAP_DB_PASS:-}" ]]; then
        notice "Using MediTap credentials from environment variables."
        MT_DB_NAME="${MEDITAP_DB_NAME}"
        MT_DB_USER="${MEDITAP_DB_USER}"
        MT_DB_PASS="${MEDITAP_DB_PASS}"
        dump_database "${MT_DB_NAME}" "${MT_DB_USER}" "${MT_DB_PASS}" || true
    else
        notice "/var/www/meditap exists but no MEDITAP_DB_* env vars set — skipping MediTap backup."
        notice "Set MEDITAP_DB_NAME, MEDITAP_DB_USER, MEDITAP_DB_PASS to enable MediTap backups."
    fi
else
    log "MediTap directory (${MEDITAP_DIR}) not found — skipping MediTap backup."
fi

# ── 5. Remove old backups ─────────────────────────────────────────────────────
log "Removing backups older than ${RETENTION_DAYS} days from ${BACKUP_DIR}..."
DELETED=0
while IFS= read -r -d '' old_file; do
    rm -f "${old_file}"
    log "  Deleted: ${old_file}"
    (( DELETED++ )) || true
done < <(find "${BACKUP_DIR}" -name "*.sql.gz" -mtime "+${RETENTION_DAYS}" -print0 2>/dev/null)

if [[ $DELETED -eq 0 ]]; then
    log "  No old backups to remove."
else
    ok "  Removed ${DELETED} old backup file(s)."
fi

# ── 6. Final status ───────────────────────────────────────────────────────────
echo ""
if $SUCCESS; then
    ok "Backup complete. Files are in ${BACKUP_DIR}/"
    exit 0
else
    fail "Backup finished with one or more errors. Check output above."
    exit 1
fi
