#!/bin/bash
# ═══════════════════════════════════════════════════════════════════
# SciLit — PostgreSQL 数据库定时备份脚本
# ═══════════════════════════════════════════════════════════════════
#
# 用法:
#   ./scripts/backup.sh                    # 备份到默认目录
#   ./scripts/backup.sh /path/to/backups   # 备份到指定目录
#
# 定时执行（crontab）:
#   0 3 * * * /root/scilit-oncology/scripts/backup.sh /data/backups
#   (每天凌晨3点备份，保留最近30天)
#
# 前置条件:
#   - 服务器上已安装 PostgreSQL 客户端（pg_dump）
#   - .env 文件在项目根目录（含 PG_PASSWORD）
# ═══════════════════════════════════════════════════════════════════

set -euo pipefail

# ── 配置 ─────────────────────────────────────────────────────────
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
ENV_FILE="${PROJECT_DIR}/.env"

# 默认备份目录
BACKUP_DIR="${1:-${PROJECT_DIR}/backups}"
RETENTION_DAYS=30

# 从 .env 文件加载 PG_PASSWORD（如果存在）
if [ -f "$ENV_FILE" ]; then
    set -a
    source "$ENV_FILE"
    set +a
fi

# 数据库连接信息（docker-compose 内部用 postgres 主机名，外部用 localhost）
PG_HOST="${PG_HOST:-localhost}"
PG_PORT="${PG_PORT:-5432}"
PG_DATABASE="${PG_DATABASE:-scilit}"
PG_USER="${PG_USER:-scilit}"
PG_PASSWORD="${PG_PASSWORD:-}"

# ── 颜色 ─────────────────────────────────────────────────────────
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

info()  { echo -e "${GREEN}[✓]${NC} $1"; }
warn()  { echo -e "${YELLOW}[!]${NC} $1"; }
error() { echo -e "${RED}[✗]${NC} $1"; exit 1; }

# ── 检查依赖 ─────────────────────────────────────────────────────
command -v pg_dump >/dev/null 2>&1 || error "pg_dump not found. Install postgresql-client."

# ── 创建备份目录 ────────────────────────────────────────────────
mkdir -p "$BACKUP_DIR"

# ── 执行备份 ─────────────────────────────────────────────────────
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/scilit_${TIMESTAMP}.sql.gz"

echo "── 数据库备份 ──"
info "数据库: ${PG_DATABASE}@${PG_HOST}:${PG_PORT}"
info "输出:   ${BACKUP_FILE}"

PGPASSWORD="${PG_PASSWORD}" pg_dump \
    --host="${PG_HOST}" \
    --port="${PG_PORT}" \
    --username="${PG_USER}" \
    --dbname="${PG_DATABASE}" \
    --format=custom \
    --compress=9 \
    --verbose \
    --no-owner \
    --no-privileges \
    --exclude-table-data='pipeline_runs' \
    --exclude-table-data='api_usage_logs' \
    2>/dev/null | gzip > "${BACKUP_FILE}"

# 验证
if [ -f "${BACKUP_FILE}" ] && [ -s "${BACKUP_FILE}" ]; then
    FILE_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
    info "备份完成 (${FILE_SIZE})"
else
    error "备份文件为空或不存在"
fi

# ── 清理旧备份 ───────────────────────────────────────────────────
find "${BACKUP_DIR}" -name "scilit_*.sql.gz" -type f -mtime +${RETENTION_DAYS} -delete
info "已清理 ${RETENTION_DAYS} 天前的备份"

# ── 恢复指南 ─────────────────────────────────────────────────────
echo ""
echo "── 恢复命令（如需） ──"
echo "  gunzip -c ${BACKUP_FILE} | PGPASSWORD=\${PG_PASSWORD} psql -h \${PG_HOST} -U ${PG_USER} -d ${PG_DATABASE}"
echo "  # 或:  gunzip -c ${BACKUP_FILE} > restore.sql && psql ... -f restore.sql"
