#!/usr/bin/env python3
"""
Build an artifact index for the RU↔host-structure bundle.

Outputs:
- sources/artifact_index.json
- docs/Artifacts.md

This is a "breakthrough posture" piece: it makes the package auditable at a glance.
"""

from __future__ import annotations
import os, json, glob, argparse
from typing import Any, Dict, List, Optional

def load(p: str) -> Dict[str, Any]:
    with open(p,"r",encoding="utf-8") as f:
        return json.load(f)

def dump(p: str, obj: Dict[str, Any]) -> None:
    os.makedirs(os.path.dirname(p), exist_ok=True)
    with open(p,"w",encoding="utf-8") as f:
        json.dump(obj, f, indent=2)

def rel(root: str, p: str) -> str:
    return os.path.relpath(p, root).replace("\\","/")

def classify_bridge(b: Dict[str, Any]) -> str:
    cl = (b.get("universality_claim") or {}).get("claim_level","")
    if cl == "in_class_universality":
        return "CONTRACTION_CERTIFIED"
    if cl == "non_universality_obstruction":
        # Try to infer OG type from robust certificate path or text
        concl = (b.get("universality_claim") or {}).get("conclusion","").lower()
        if "og1" in concl or "period" in concl:
            return "OG1_PERIODIC_CORE"
        if "og2" in concl or "active" in concl:
            return "OG2_ACTIVE_FACE_INCONSISTENCY"
        if "og3" in concl or "no doeblin" in concl:
            return "OG3_NO_DOEBLIN"
        if "og4" in concl or "avoidable" in concl:
            return "OG4_AVOIDABLE_DOEBLIN"
        return "OBSTRUCTION"
    return "UNCLASSIFIED"

def extract_key_fields(b: Dict[str, Any]) -> Dict[str, Any]:
    sc = b.get("string_context") or {}
    red = b.get("reduction") or {}
    claim = b.get("universality_claim") or {}
    refs = b.get("ru_certificate_refs") or {}
    return {
        "host_name": sc.get("name"),
        "host_sector": sc.get("finite_sector"),
        "cone": sc.get("positivity_cone"),
        "claim_level": claim.get("claim_level"),
        "conclusion": claim.get("conclusion"),
        "robust_certificate": refs.get("robust_certificate_instance"),
        "global_report": refs.get("global_report_instance"),
        "state_graph": red.get("state_graph"),
    }

def main()->int:
    ap=argparse.ArgumentParser()
    ap.add_argument("--root", default=".", help="Project root")
    args=ap.parse_args()
    root=os.path.abspath(args.root)

    bridges = sorted(glob.glob(os.path.join(root,"sources","ru_bridge","bridge_certificate_*.json")))
    robusts = sorted(glob.glob(os.path.join(root,"sources","ru","robust_certificate_*.json")))
    globals_ = sorted(glob.glob(os.path.join(root,"sources","ru","global_universality_report_*.json")))
    models = sorted(glob.glob(os.path.join(root,"sources","ru_bridge","*_model.json")))

    items: List[Dict[str, Any]] = []
    for bp in bridges:
        b = load(bp)
        cls = classify_bridge(b)
        items.append({
            "type": "bridge_certificate",
            "class": cls,
            "path": rel(root, bp),
            "fields": extract_key_fields(b),
        })

    index = {
        "schema_version": "1.0",
        "counts": {
            "bridge_certificates": len(bridges),
            "robust_certificates": len(robusts),
            "global_reports": len(globals_),
            "models": len(models),
        },
        "paths": {
            "bridge_certificates": [rel(root,p) for p in bridges],
            "robust_certificates": [rel(root,p) for p in robusts],
            "global_reports": [rel(root,p) for p in globals_],
            "models": [rel(root,p) for p in models],
        },
        "items": items,
    }

    out_json = os.path.join(root,"sources","artifact_index.json")
    dump(out_json, index)

    # Build a human-readable markdown index
    by_class: Dict[str, List[Dict[str, Any]]] = {}
    for it in items:
        by_class.setdefault(it["class"], []).append(it)

    lines: List[str] = []
    lines.append("# Artifact Index\n")
    lines.append("This index is generated by `tools/build_artifact_index.py`.\n")
    lines.append("## Counts\n")
    lines.append(f"- Bridge certificates: {index['counts']['bridge_certificates']}")
    lines.append(f"- Robust certificates: {index['counts']['robust_certificates']}")
    lines.append(f"- Global reports: {index['counts']['global_reports']}")
    lines.append(f"- Models: {index['counts']['models']}\n")

    lines.append("## Audited outcomes (grouped)\n")
    for cls in sorted(by_class.keys()):
        lines.append(f"### {cls}\n")
        for it in by_class[cls]:
            f = it["fields"]
            lines.append(f"- **{f.get('host_name')}** — `{it['path']}`")
            if f.get("robust_certificate"):
                lines.append(f"  - robust: `{f.get('robust_certificate')}`")
            if f.get("global_report"):
                lines.append(f"  - global: `{f.get('global_report')}`")
            if f.get("conclusion"):
                # keep short
                c = f.get("conclusion").strip().replace("\n"," ")
                if len(c) > 220:
                    c = c[:220] + " (truncated)"
                lines.append(f"  - conclusion: {c}")
        lines.append("")

    lines.append("## Machine-readable index\n")
    lines.append(f"- `sources/artifact_index.json`\n")

    out_md = os.path.join(root,"docs","Artifacts.md")
    os.makedirs(os.path.dirname(out_md), exist_ok=True)
    with open(out_md,"w",encoding="utf-8") as f:
        f.write("\n".join(lines))

    print("Wrote:")
    print(" ", rel(root,out_json))
    print(" ", rel(root,out_md))
    return 0

if __name__=="__main__":
    raise SystemExit(main())
