#!/usr/bin/env python3
"""Backup online SQLite (T7) — copie consistenta a bazei pe volum persistent.

SQLite in WAL NU se copiaza sigur cu `cp` (WAL-ul poate avea tranzactii necheckpoint-ate).
Folosim API-ul `Connection.backup` (online, consistent, fara oprirea worker-ului).

Utilizare:
    python -m tools.backup                      # -> <db_dir>/backups/autopass-YYYYMMDD-HHMMSS.db
    python -m tools.backup --out /path/snap.db  # destinatie explicita
    python -m tools.backup --keep 14            # pastreaza ultimele 14, sterge restul

Recomandat: rulat dintr-un cron pe gazda (ex. zilnic), tinta pe volum/montaj separat.
"""

from __future__ import annotations

import argparse
import sqlite3
import sys
from datetime import datetime, timezone
from pathlib import Path

from app.config import get_settings


def backup_db(src: Path, dest: Path) -> Path:
    """Backup online (consistent) din `src` in `dest`. Intoarce `dest`."""
    dest.parent.mkdir(parents=True, exist_ok=True)
    src_conn = sqlite3.connect(src)
    try:
        dst_conn = sqlite3.connect(dest)
        try:
            src_conn.backup(dst_conn)
        finally:
            dst_conn.close()
    finally:
        src_conn.close()
    return dest


def prune(backup_dir: Path, keep: int) -> list[Path]:
    """Pastreaza cele mai noi `keep` snapshot-uri (dupa nume = timestamp), sterge restul."""
    snaps = sorted(backup_dir.glob("autopass-*.db"), reverse=True)
    removed = []
    for old in snaps[keep:]:
        old.unlink(missing_ok=True)
        removed.append(old)
    return removed


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Backup online SQLite gateway RAR AUTOPASS")
    parser.add_argument("--out", type=Path, default=None, help="destinatie explicita (default: <db_dir>/backups/)")
    parser.add_argument("--keep", type=int, default=0, help="pastreaza ultimele N snapshot-uri (0 = nu sterge)")
    args = parser.parse_args(argv)

    src = get_settings().db_path
    if not src.exists():
        print(f"eroare: baza {src} nu exista", file=sys.stderr)
        return 1

    if args.out is not None:
        dest = args.out
    else:
        stamp = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
        dest = src.parent / "backups" / f"autopass-{stamp}.db"

    backup_db(src, dest)
    print(f"backup -> {dest} ({dest.stat().st_size} bytes)")

    if args.keep > 0:
        removed = prune(dest.parent, args.keep)
        if removed:
            print(f"sterse {len(removed)} snapshot-uri vechi (pastrez {args.keep})")
    return 0


if __name__ == "__main__":
    sys.exit(main())
