"""File-backed persistence adapter (JSON in data/runs/)."""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any, Dict, List, Optional

from .adapter import PersistenceAdapter


class FilePersistenceAdapter(PersistenceAdapter):
    """Persist workflow runs as JSON files under a local directory."""

    def __init__(self, base_dir: str = "data/runs"):
        self.base_dir = Path(base_dir)
        self.base_dir.mkdir(parents=True, exist_ok=True)

    def _run_path(self, run_id: str) -> Path:
        return self.base_dir / f"{run_id}.json"

    def save_run(self, run_id: str, summary: Dict[str, Any]) -> None:
        payload = {"run_id": run_id, **summary}
        self._run_path(run_id).write_text(
            json.dumps(payload, indent=2, default=str), encoding="utf-8"
        )

    def load_run(self, run_id: str) -> Optional[Dict[str, Any]]:
        path = self._run_path(run_id)
        if not path.exists():
            return None
        return json.loads(path.read_text(encoding="utf-8"))

    def save_artifact_meta(self, run_id: str, artifact: Dict[str, Any]) -> None:
        arts_dir = self.base_dir / run_id / "artifacts"
        arts_dir.mkdir(parents=True, exist_ok=True)
        name = artifact.get("name", "artifact")
        path = arts_dir / f"{name}.meta.json"
        path.write_text(json.dumps(artifact, indent=2, default=str), encoding="utf-8")

    def list_runs(self, limit: int = 20) -> List[Dict[str, Any]]:
        runs: List[Dict[str, Any]] = []
        for path in sorted(self.base_dir.glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True):
            if len(runs) >= limit:
                break
            try:
                runs.append(json.loads(path.read_text(encoding="utf-8")))
            except (json.JSONDecodeError, OSError):
                continue
        return runs
