"""Transactional SQLite restore, tested with a second connection before touching the live cache."""
import json
import pathlib
import shutil
import sqlite3
import sys
import time

sys.stdout.reconfigure(encoding="utf-8")
root = pathlib.Path(sys.argv[1]).resolve()
source_path = root / "validated-markets-03.db"
source = sqlite3.connect(source_path.as_uri() + "?mode=ro", uri=True)
if source.execute("PRAGMA integrity_check").fetchall() != [("ok",)]:
    raise RuntimeError("Recovery candidate failed integrity checking")
expected = tuple(source.execute("SELECT (SELECT count(*) FROM stations),(SELECT count(*) FROM quotes),(SELECT count(*) FROM snapshots)").fetchone())
if min(expected) < 1000:
    raise RuntimeError("Unexpectedly small recovery candidate")
apply_live = len(sys.argv) > 2
if apply_live:
    live = pathlib.Path(sys.argv[2]).resolve()
    if live.name != "markets.db" or live == source_path:
        raise RuntimeError("Explicit market database target required")
    # A coherent SQLite backup retains the exact current state, including its WAL.
    snapshot_path = root / "before-restore-online.db"
    if snapshot_path.exists():
        raise RuntimeError("Refusing to overwrite the pre-restore backup")
    with sqlite3.connect(live.as_uri() + "?mode=ro", uri=True) as current, sqlite3.connect(snapshot_path) as snapshot:
        current.backup(snapshot)
else:
    live = root / "restore-simulation.db"
    if live.exists():
        raise RuntimeError("Use a fresh simulation target")
    for suffix in ("", "-wal", "-shm"):
        original = root / ("markets.db" + suffix)
        if original.exists():
            shutil.copy2(original, pathlib.Path(str(live) + suffix))
reader = sqlite3.connect(live.as_uri() + "?mode=ro", uri=True, timeout=20)
before_error = None
try:
    reader.execute("SELECT count(*) FROM quotes").fetchone()
except sqlite3.DatabaseError as error:
    before_error = str(error)
started = time.monotonic()
def progress(status, remaining, total):
    if time.monotonic() - started > 45:
        raise TimeoutError("Restore deadline exceeded; SQLite rolls back the destination transaction")
with sqlite3.connect(live, timeout=20) as destination:
    source.backup(destination, pages=512, progress=progress, sleep=.05)
after = tuple(reader.execute("SELECT (SELECT count(*) FROM stations),(SELECT count(*) FROM quotes),(SELECT count(*) FROM snapshots)").fetchone())
integrity = reader.execute("PRAGMA integrity_check").fetchall()
report = {"live": apply_live, "target": str(live), "before_error": before_error, "expected": expected, "actual": after,
          "existing_connection_sees_restored_database": after == expected, "integrity": integrity,
          "elapsed_seconds": time.monotonic() - started, "api": "sqlite3_backup", "raw_files_replaced": False}
(root / ("live-restore-report.json" if apply_live else "restore-simulation-report.json")).write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(report, ensure_ascii=False), flush=True)
if after != expected or integrity != [("ok",)]:
    raise RuntimeError("Restored cache validation failed")
