#!/usr/bin/env python3
"""SimVSM-Korpus-Inventar (Prompt §5.1) — deterministisch, ohne LLM.
Liest alle *.json im Korpus, schreibt _inventar.json + kompakte Zusammenfassung."""
import json, os, re, sys, collections

KORPUS = "/home/aria/work/simvsm-korpus"
OUT = "/home/aria/work/simvsm-analyse/_inventar.json"

def family_of(name):
    """Normalisiert Dateinamen auf Wertstrom-Familie (Datums-/Versions-/Alt-Suffixe weg)."""
    n = os.path.splitext(name)[0]
    n = re.sub(r'\(\d+\)', '', n)                        # (1), (2)
    n = re.sub(r'(?i)[_ ]?(stand|alt\d*|alternative|rev\d+|LV[-_]?Line|Default Value Stream|Standard[- ]?(Wertstrom|Modell)(_\d+)?|Valuestream[_ ]?CW\d+.*|V\d+_\d+|Basis.*|incl.*|\d{1,2}Uhr.*|KF.*|LSC.*|OP\d+.*|FIFO.*|WIP.*|startingpoint.*|\d+x[_ ]?\w+)$', '', n)
    n = re.sub(r'(?i)_?(0?\d{6,8}|\d{2}\.\d{2}\.\d{4})', '', n)  # Datums-Tokens
    n = re.sub(r'[_ ]+$', '', n).strip(' _-')
    return n or os.path.splitext(name)[0]

inv = {"files": [], "node_class_census": collections.Counter(), "link_class_census": collections.Counter(),
       "param_class_by_node": collections.defaultdict(collections.Counter), "versions": collections.Counter(),
       "families": collections.defaultdict(lambda: {"json": [], "svg": []})}

for fn in sorted(os.listdir(KORPUS)):
    path = os.path.join(KORPUS, fn)
    fam = family_of(fn)
    if fn.endswith(".svg"):
        inv["families"][fam]["svg"].append(fn)
        continue
    if not fn.endswith(".json"):
        continue
    inv["families"][fam]["json"].append(fn)
    entry = {"file": fn, "size": os.path.getsize(path), "family": fam, "parse": "ok"}
    try:
        d = json.load(open(path, encoding="utf-8"))
    except Exception as e:
        entry["parse"] = f"FAIL: {e}"[:120]
        inv["files"].append(entry); continue
    entry["name"] = d.get("name"); entry["description"] = (d.get("description") or "")[:80]
    entry["createdWithVersion"] = d.get("createdWithVersion"); entry["mainVersion"] = d.get("mainVersion")
    inv["versions"][f"{d.get('mainVersion')}→{d.get('createdWithVersion')}"] += 1
    entry["top_level_keys"] = sorted(d.keys())
    s = d.get("settings", {}) or {}
    entry["settings_keys"] = sorted(s.keys())
    entry["n_products"] = len(s.get("products", []) or [])
    entry["n_shift_calendars"] = len(s.get("shiftCalendars", []) or [])
    alts = d.get("alternatives", []) or []
    entry["alternatives"] = []
    for a in alts:
        m = (a.get("model") or {})
        nda, lda = m.get("nodeDataArray", []) or [], m.get("linkDataArray", []) or []
        ncls = collections.Counter(str(n.get("class", n.get("category","?"))) for n in nda)
        lcls = collections.Counter(str(l.get("class", l.get("category","?"))) for l in lda)
        inv["node_class_census"].update(ncls); inv["link_class_census"].update(lcls)
        for n in nda:
            c = str(n.get("class", n.get("category","?")))
            for p in n.get("parameters", []) or []:
                inv["param_class_by_node"][c][str(p.get("class","?"))] += 1
        entry["alternatives"].append({
            "name": a.get("name"), "isMain": a.get("isMain"),
            "nodes": len(nda), "links": len(lda),
            "node_classes": dict(ncls), "has_resultData": bool(a.get("resultData")),
            "extensions": sorted((a.get("extensions") or {}).keys()),
        })
    unknown = [k for k in d.keys() if k not in {"alternatives","createdWithVersion","mainVersion","name","description","settings"}]
    entry["unknown_top_level"] = unknown
    inv["files"].append(entry)

out = {
  "files": inv["files"],
  "node_class_census": dict(inv["node_class_census"].most_common()),
  "link_class_census": dict(inv["link_class_census"].most_common()),
  "param_class_by_node": {k: dict(v.most_common()) for k,v in inv["param_class_by_node"].items()},
  "versions": dict(inv["versions"]),
  "families": {k: v for k,v in sorted(inv["families"].items())},
}
json.dump(out, open(OUT,"w",encoding="utf-8"), indent=1, ensure_ascii=False)

# Kompakt-Zusammenfassung
print(f"JSON-Dateien: {sum(1 for f in inv['files'])}, Familien: {len(out['families'])}")
print(f"Versionen (main→created): {out['versions']}")
tot_alts = sum(len(f.get('alternatives',[])) for f in inv['files'])
tot_nodes = sum(a['nodes'] for f in inv['files'] for a in f.get('alternatives',[]))
print(f"Alternativen gesamt: {tot_alts}, Nodes gesamt: {tot_nodes}")
print(f"\nNODE-KLASSEN ({len(out['node_class_census'])}):")
for k,v in out["node_class_census"].items(): print(f"  {k}: {v}")
print(f"\nLINK-KLASSEN ({len(out['link_class_census'])}):")
for k,v in out["link_class_census"].items(): print(f"  {k}: {v}")
print("\nFAMILIEN (json/svg):")
for k,v in out["families"].items(): print(f"  {k}: {len(v['json'])}J/{len(v['svg'])}S")
print("\nUNBEKANNTE TOP-LEVEL-KEYS:", set(k for f in inv['files'] for k in f.get('unknown_top_level',[])) or "keine")
print("resultData befüllt in:", sum(1 for f in inv['files'] for a in f.get('alternatives',[]) if a['has_resultData']), "Alternativen")
print("Extensions-Keys:", set(x for f in inv['files'] for a in f.get('alternatives',[]) for x in a['extensions']) or "keine")
