#!/bin/bash
# =============================================================================
# DashCaddy Gitea — Off-host backup to Dropbox
# =============================================================================
# - Stops gitea container briefly to ensure SQLite DB consistency
# - Syncs /var/lib/docker/volumes/gitea-data to dropbox:/Apps/dashcaddy-gitea-backups/<date>/
# - Date-stamped snapshots (one per day), kept for 7 days locally
# - Restarts gitea even if sync fails
# - Logs to /var/log/gitea-backup.log
# =============================================================================
set -u  # don't use -e: we want to always restart gitea

LOG=/var/log/gitea-backup.log
DATA_SRC=/var/lib/docker/volumes/gitea-data/_data
DEST="dropbox:/Apps/dashcaddy-gitea-backups"
TODAY=$(date -u +%Y-%m-%d)
BACKUP_PATH="${DEST}/${TODAY}"
RETENTION_DAYS=7

log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" | tee -a "$LOG"; }

log "=== Backup start ==="

# 0. Sanity checks
if [ ! -d "$DATA_SRC" ]; then
  log "ERROR: data dir $DATA_SRC missing"
  exit 1
fi

# 1. Stop gitea to flush SQLite
log "Stopping gitea container..."
docker stop gitea >> "$LOG" 2>&1
STOP_RC=$?
if [ $STOP_RC -ne 0 ]; then
  log "WARNING: docker stop returned $STOP_RC — container may not be running"
fi

# 2. Sync (use copy so source files are preserved as-is, no --delete)
log "Syncing $DATA_SRC -> $BACKUP_PATH"
rclone copy "$DATA_SRC" "$BACKUP_PATH" \
  --transfers 4 \
  --checkers 8 \
  --retries 3 \
  --low-level-retries 10 \
  --stats 30s \
  --log-file "$LOG" \
  --log-level INFO
SYNC_RC=$?

# 3. Always restart gitea
log "Starting gitea container..."
docker start gitea >> "$LOG" 2>&1
START_RC=$?

# Wait for gitea to be ready
for i in {1..30}; do
  if curl -sf http://localhost:3000/api/v1/version > /dev/null 2>&1; then
    log "Gitea is up after ${i}s"
    break
  fi
  sleep 1
done

# 4. Cleanup old backups (older than RETENTION_DAYS)
log "Pruning local + remote snapshots older than ${RETENTION_DAYS} days..."
CUTOFF=$(date -u -d "${RETENTION_DAYS} days ago" +%Y-%m-%d)
rclone lsf "$DEST/" --dirs-only 2>/dev/null | while read -r d; do
  # rclone returns names with trailing /
  name="${d%/}"
  if [[ "$name" < "$CUTOFF" ]]; then
    log "  removing old: $name"
    rclone purge "${DEST}/${name}" >> "$LOG" 2>&1
  fi
done

# 5. Report
if [ $SYNC_RC -eq 0 ] && [ $START_RC -eq 0 ]; then
  log "=== Backup OK ==="
  exit 0
else
  log "=== Backup completed with errors (sync=$SYNC_RC, start=$START_RC) ==="
  exit 1
fi
