"""Zeitmaschine — Snapshots ansehen und per Klick zu einem Stand zurückkehren.

Die Maschinerie existiert komplett (deploy/backup.sh Timer 03:30, Off-Box-Kopie,
deploy/restore.sh mit Pre-Restore-Sicherung); hier kommt nur der letzte Meter dazu:
Liste + Inhalt in der UI und ein Restore-Start als EIGENE systemd-Unit — restore.sh
stoppt mission-control-2 selbst, als Kind des Backends stürbe der Lauf mittendrin."""

import os
import re
import subprocess
import time
from pathlib import Path

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

from services import backup as backup_svc

router = APIRouter(prefix="/api")

_REPO_ROOT = Path(__file__).resolve().parents[2]
RESTORE_SH = _REPO_ROOT / "deploy" / "restore.sh"
_FILE_RX = re.compile(r"^mc2-state-[0-9T:_-]+\.tar\.gz$")


class RestoreIn(BaseModel):
    file: str


@router.get("/zeitmaschine")
def list_snapshots() -> dict:
    return {"available": os.name == "posix", "backups": backup_svc.list_backups()}


@router.get("/zeitmaschine/inhalt")
def snapshot_contents(file: str) -> dict:
    """Top-Level-Komponenten eines Snapshots (mem0, hermes, llama-swap, MANIFEST …)."""
    if not _FILE_RX.match(file):
        raise HTTPException(400, "Ungültiger Snapshot-Name.")
    p = backup_svc.BACKUP_DIR / file
    if not p.is_file():
        raise HTTPException(404, "Snapshot nicht gefunden.")
    return {"file": file, "components": backup_svc.snapshot_components(p)}


@router.post("/zeitmaschine/restore")
def restore(body: RestoreIn) -> dict:
    """Wiederherstellung starten (detached). restore.sh macht VORHER selbst ein
    Sicherheits-Backup des aktuellen Zustands — der Schritt ist also reversibel."""
    if os.name != "posix":
        raise HTTPException(400, "Wiederherstellen geht nur auf der Box.")
    if not _FILE_RX.match(body.file):
        raise HTTPException(400, "Ungültiger Snapshot-Name.")
    if not (backup_svc.BACKUP_DIR / body.file).is_file():
        raise HTTPException(404, "Snapshot nicht gefunden.")

    try:
        from services import announce
        announce.add(f"Zeitmaschine: Wiederherstellung von {body.file} gestartet — "
                     "die Dienste starten gleich neu.", "[Zeitmaschine]", "zeitmaschine", "silent")
    except Exception:
        pass

    unit = f"mc2-restore-{int(time.time())}"
    r = subprocess.run(
        ["systemd-run", "--user", "--collect", f"--unit={unit}",
         "/bin/bash", str(RESTORE_SH), "--yes", body.file],
        capture_output=True, text=True, timeout=20)
    if r.returncode != 0:
        raise HTTPException(500, f"Start fehlgeschlagen: {(r.stderr or r.stdout).strip()[:300]}")
    return {"ok": True, "unit": unit}
