\
from __future__ import annotations
import csv, os
from dataclasses import asdict
from typing import Dict, List, Optional
from .scan import CaseMeta

REGISTRY_FIELDS = [
    "case_id","case_name","case_dir",
    "engine","version","eos",
    "io_signature","mesh_type","n_elements","n_connections",
    "fields_hash","files_hash",
    "status","tested_on","toughanimator_commit",
    "source","notes","last_seen"
]

def load_registry(path: str) -> Dict[str, dict]:
    if not os.path.isfile(path):
        return {}
    out: Dict[str, dict] = {}
    with open(path, "r", newline="", encoding="utf-8") as f:
        rdr = csv.DictReader(f)
        for row in rdr:
            if row.get("case_id"):
                out[row["case_id"]] = row
    return out

def upsert_registry(existing: Dict[str, dict], metas: List[CaseMeta]) -> Dict[str, dict]:
    for m in metas:
        row = {k: "" for k in REGISTRY_FIELDS}
        d = asdict(m)
        for k in row.keys():
            if k in d:
                row[k] = d[k]
        # keep manual fields if present and new is empty
        if m.case_id in existing:
            old = existing[m.case_id]
            for k in ["status","tested_on","toughanimator_commit","source","notes"]:
                if (not row.get(k)) and old.get(k):
                    row[k] = old.get(k)
        existing[m.case_id] = row
    return existing

def write_registry_csv(path: str, registry: Dict[str, dict]) -> None:
    os.makedirs(os.path.dirname(path), exist_ok=True)
    # stable order: by engine then case_name
    rows = list(registry.values())
    rows.sort(key=lambda r: (r.get("engine",""), r.get("case_name","")))
    with open(path, "w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=REGISTRY_FIELDS)
        w.writeheader()
        for r in rows:
            w.writerow({k: r.get(k,"") for k in REGISTRY_FIELDS})
