#!/bin/bash
set -euo pipefail

# ============================================================
# backup_search_db.sh — search.db 本地备份 (纯本地, 无GDrive推送)
# 2026-08-24 加固: 空间预检 (VACUUM 需要源库×2+2G)
# 2026-08-24 暂停: GDrive推送段已移除 (代理带宽不足, 待优化方案)
# ============================================================

DB_PATH=/mnt/data/search.db
BACKUP_DIR=/mnt/data/backups/db
RETENTION=3
TIMESTAMP=$(date +%Y%m%d_%H%M)
LOGFILE=/var/log/backup_search_db.log

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOGFILE"; }

mkdir -p "$BACKUP_DIR"

# 清理之前中断残留的 .db 文件
find "$BACKUP_DIR" -name 'search_*.db' -type f -delete

if [ ! -f "$DB_PATH" ]; then
    log "❌ search.db not found at $DB_PATH"
    exit 1
fi

DB_SIZE=$(du -h "$DB_PATH" | cut -f1)
log "Starting search.db backup (source: $DB_SIZE)..."

# ⚠️ 2026-08-24 加固: 空间预检 —— VACUUM INTO 需要 源库大小 + 压缩包 的双倍空间
# 上次 (8/24 03:30) 因磁盘写爆导致备份失败 + 日跑导入全失败 + OOM 崩溃
DB_BYTES=$(stat -c %s "$DB_PATH")
FREE_MT=$(df -Pk /mnt/data | tail -1 | awk '{print $4}')
FREE_MT_GB=$((FREE_MT / 1024 / 1024))
NEED_GB=$((DB_BYTES / 1024 / 1024 / 1024 * 2 + 2))
if [ "$FREE_MT_GB" -lt "$NEED_GB" ]; then
    log "❌ 空间不足: /mnt/data 可用 ${FREE_MT_GB}G, 需要 ≥${NEED_GB}G (源库 ${DB_SIZE}×2+2G), 跳过本次备份"
    exit 1
fi
log "空间预检通过: /mnt/data 可用 ${FREE_MT_GB}G ≥ ${NEED_GB}G"

TMP_DB="${BACKUP_DIR}/search_${TIMESTAMP}.db"
GZ_FILE="${TMP_DB}.gz"

# VACUUM INTO 失败时清理残留 (防止下次把磁盘写爆)
if ! sqlite3 "$DB_PATH" "VACUUM INTO '$TMP_DB'"; then
    log "❌ VACUUM INTO 失败, 清理残留"
    rm -f "$TMP_DB"
    exit 1
fi
TMP_SIZE=$(du -h "$TMP_DB" | cut -f1)
log "VACUUM INTO done: $TMP_SIZE"

gzip -c "$TMP_DB" > "$GZ_FILE"
rm -f "$TMP_DB"
GZ_SIZE=$(du -h "$GZ_FILE" | cut -f1)
log "Compressed: $GZ_FILE ($GZ_SIZE)"

# 保留7份
cd "$BACKUP_DIR"
COUNT=$(ls search_*.db.gz 2>/dev/null | wc -l)
if [ "$COUNT" -gt "$RETENTION" ]; then
    TO_DELETE=$((COUNT - RETENTION))
    log "Removing $TO_DELETE old backup(s)..."
    ls -1 search_*.db.gz | sort | head -n $TO_DELETE | while read f; do
        rm -f "$f"
        log "  removed: $f"
    done
fi

log "✅ Done"
