#!/usr/bin/env python3
"""Summarize current selector-root paths that mention the map1_01a frontier."""
from __future__ import annotations

import argparse
import html
import json
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "out"
LABEL = "2:0"
ROOT_HEX = "0x00540714"
SOURCE = "map1_01a"
TARGET = "map2_02d"
FRONTIER_LEAVES = ["0x00542ac0", "0x00542ad4", "0x00542ae8"]
FAILED_CURRENT_ROOT_FRONTIER_GATE_IDS = [
    "normal-current-root-execution",
    "strict-source-hotspot",
    "frontier-event-cluster",
    "reader-branch-target-linkage",
]
CURRENT_ROOT_FRONTIER_MISSING_EVIDENCE = [
    "normal runtime execution selecting current root 2:0 and frontier reader leaf 0x00542ae8",
    "strict map1_01a source coordinate or hotspot linked to map2_02d",
    "non-selector-only frontier event cluster linking map1_01a to map2_02d",
    "reader branch outcome proving a field-map target on the normal route path",
]
CURRENT_ROOT_FRONTIER_EVIDENCE_REFS = [
    {
        "path": "out/save_scene_selector_references.json",
        "fields": ["label", "pathHex", "kind", "resource"],
    },
    {
        "path": "out/save_selector_leaf_streams.json",
        "fields": ["leafPointerHex", "linkedCns", "nestedPointerHex"],
    },
    {
        "path": "out/save_selector_stream_traces.json",
        "fields": ["streamVaHex", "trace", "stopReason"],
    },
    {
        "path": "out/map1_01a_hotspot_gap.json",
        "fields": ["strictHotspotFound", "promotionStatus"],
    },
    {
        "path": "out/field_map_record_roots.json",
        "fields": ["clusters", "currentFrontierCount", "classification"],
    },
]


def unique(values: list[str]) -> list[str]:
    seen = set()
    result = []
    for value in values:
        if value in seen:
            continue
        seen.add(value)
        result.append(value)
    return result


def build_summary(
    references: list[dict],
    leaf_streams: list[dict],
    stream_traces: list[dict],
    hotspot_gap: dict,
    field_roots: dict,
) -> dict:
    by_leaf: dict[str, list[dict]] = {leaf: [] for leaf in FRONTIER_LEAVES}
    for row in references:
        if row.get("label") != LABEL:
            continue
        path = row.get("pathHex") or []
        if not path or path[0] != ROOT_HEX:
            continue
        leaf = next((item for item in reversed(path) if item in by_leaf), None)
        if leaf:
            by_leaf[leaf].append(row)

    trace_by_stream = {row.get("streamVaHex"): row for row in stream_traces}
    leaf_stream_by_leaf = {row.get("leafPointerHex"): row for row in leaf_streams}
    leaf_rows = []
    for leaf in FRONTIER_LEAVES:
        rows = by_leaf.get(leaf) or []
        field_maps = unique([row["resource"] for row in rows if row.get("kind") == "fieldMap"])
        cns = unique([row["resource"] for row in rows if row.get("kind") == "cns"])
        map1_rows = [row for row in rows if row.get("resource") == SOURCE]
        map2_rows = [row for row in rows if row.get("resource") == TARGET]
        trace = trace_by_stream.get(leaf) or {}
        stop = (trace.get("trace") or [{}])[-1].get("stopReason") if trace.get("trace") else None
        has_reader = any(item.get("vaHex") == "0x00542b0c" for item in trace.get("trace") or [])
        leaf_stream = leaf_stream_by_leaf.get(leaf) or {}
        leaf_rows.append(
            {
                "leafPointerHex": leaf,
                "referenceCount": len(rows),
                "fieldMaps": field_maps,
                "hasSource": SOURCE in field_maps,
                "hasTarget": TARGET in field_maps,
                "sourceTilesets": unique(sum((row.get("tilesets") or [] for row in map1_rows), [])),
                "targetTilesets": unique(sum((row.get("tilesets") or [] for row in map2_rows), [])),
                "sourceRecordRefs": unique([row.get("refVaHex") for row in map1_rows if row.get("refVaHex")]),
                "targetRecordRefs": unique([row.get("refVaHex") for row in map2_rows if row.get("refVaHex")]),
                "linkedCns": leaf_stream.get("linkedCns") or cns,
                "traceStopReason": stop,
                "traceContainsFrontierReader": has_reader,
                "nestedPointerHex": leaf_stream.get("nestedPointerHex"),
            }
        )

    clusters = field_roots.get("clusters") if isinstance(field_roots, dict) else field_roots
    frontier_cluster = next(
        (
            row for row in clusters or []
            if row.get("currentFrontierCount")
            or row.get("currentFrontierPairCount")
            or row.get("classification") == "current frontier selector-only cluster"
        ),
        {},
    )
    conclusion = (
        "The current selector root 2:0 reaches map1_01a and map2_02d through save-selector leaf paths, not through a "
        "strict hotspot. Leaf 0x00542ae8 is the only traced frontier leaf that reaches reader 0x00542b0c, but the "
        "hotspot scan still has no map1_01a coordinate row and the frontier cluster is selector-only. Keep this edge "
        "blocked until a strict source or equivalent non-coordinate trigger is found."
    )
    return {
        "selector": LABEL,
        "rootHex": ROOT_HEX,
        "source": SOURCE,
        "target": TARGET,
        "leafCount": len(leaf_rows),
        "leafRows": leaf_rows,
        "strictHotspotFound": hotspot_gap.get("strictHotspotFound"),
        "hotspotPromotionStatus": hotspot_gap.get("promotionStatus"),
        "frontierClusterRangeHex": (
            frontier_cluster.get("clusterRangeHex")
            or (
                f"{frontier_cluster.get('clusterStartHex')}..{frontier_cluster.get('clusterEndHex')}"
                if frontier_cluster.get("clusterStartHex") and frontier_cluster.get("clusterEndHex")
                else None
            )
        ),
        "frontierClusterClass": frontier_cluster.get("classification") or frontier_cluster.get("class"),
        "frontierClusterEventCount": frontier_cluster.get("eventCount") or frontier_cluster.get("eventRecordCount"),
        "frontierClusterSelectorRefCount": frontier_cluster.get("selectorRefCount") or frontier_cluster.get("saveSelectorRefCount"),
        "proofFound": False,
        "currentRootFrontierProofFound": False,
        "failedCurrentRootFrontierGateIds": FAILED_CURRENT_ROOT_FRONTIER_GATE_IDS,
        "missingEvidence": CURRENT_ROOT_FRONTIER_MISSING_EVIDENCE,
        "remainingProofs": CURRENT_ROOT_FRONTIER_MISSING_EVIDENCE,
        "evidenceRefs": CURRENT_ROOT_FRONTIER_EVIDENCE_REFS,
        "evidenceRefCount": len(CURRENT_ROOT_FRONTIER_EVIDENCE_REFS),
        "promotionStatus": "blocked",
        "conclusion": conclusion,
    }


def markdown(summary: dict) -> str:
    lines = [
        "# Save Selector Current Root Frontier Paths",
        "",
        f"- selector: `{summary['selector']}` root `{summary['rootHex']}`",
        f"- route: `{summary['source']} -> {summary['target']}`",
        f"- strict hotspot found: {summary['strictHotspotFound']}",
        f"- frontier cluster: `{summary.get('frontierClusterRangeHex')}` {summary.get('frontierClusterClass')}",
        f"- proof found: {summary['proofFound']}",
        f"- failed current-root frontier gates: {', '.join(summary['failedCurrentRootFrontierGateIds'])}",
        f"- missing evidence count: {len(summary['missingEvidence'])}",
        f"- evidence refs: {summary.get('evidenceRefCount')}",
        f"- promotion status: {summary['promotionStatus']}",
        "",
        summary["conclusion"],
        "",
        "## Missing Evidence",
        "",
    ]
    lines.extend(f"- {item}" for item in summary["missingEvidence"])
    lines.extend([
        "",
        "| leaf | source? | target? | field maps | source tilesets | target tilesets | reader? | stop | nested |",
        "| --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    ])
    for row in summary["leafRows"]:
        lines.append(
            f"| `{row['leafPointerHex']}` | {'yes' if row['hasSource'] else 'no'} | "
            f"{'yes' if row['hasTarget'] else 'no'} | {', '.join(row['fieldMaps']) or '-'} | "
            f"{', '.join(row['sourceTilesets']) or '-'} | {', '.join(row['targetTilesets']) or '-'} | "
            f"{'yes' if row['traceContainsFrontierReader'] else 'no'} | {row.get('traceStopReason') or '-'} | "
            f"`{row.get('nestedPointerHex') or '-'}` |"
        )
    lines.append("")
    return "\n".join(lines)


def html_page(summary: dict) -> str:
    rows = "\n".join(
        "<tr>"
        f"<td><code>{html.escape(row['leafPointerHex'])}</code></td>"
        f"<td>{'yes' if row['hasSource'] else 'no'}</td>"
        f"<td>{'yes' if row['hasTarget'] else 'no'}</td>"
        f"<td>{html.escape(', '.join(row['fieldMaps']) or '-')}</td>"
        f"<td>{html.escape(', '.join(row['sourceTilesets']) or '-')}</td>"
        f"<td>{html.escape(', '.join(row['targetTilesets']) or '-')}</td>"
        f"<td>{'yes' if row['traceContainsFrontierReader'] else 'no'}</td>"
        f"<td>{html.escape(row.get('traceStopReason') or '-')}</td>"
        f"<td><code>{html.escape(row.get('nestedPointerHex') or '-')}</code></td>"
        "</tr>"
        for row in summary["leafRows"]
    )
    return "\n".join([
        "<!doctype html><meta charset=\"utf-8\"><title>Save Selector Current Root Frontier Paths</title>",
        "<style>body{font-family:system-ui,sans-serif;background:#111;color:#eee;max-width:1200px;margin:24px auto}table{border-collapse:collapse}td,th{border:1px solid #444;padding:6px 8px;vertical-align:top}code{color:#9bd4ff}</style>",
        "<h1>Save Selector Current Root Frontier Paths</h1>",
        f"<p>selector <code>{summary['selector']}</code> root <code>{summary['rootHex']}</code>; route <code>{summary['source']} -&gt; {summary['target']}</code>; promotion status: {html.escape(summary['promotionStatus'])}</p>",
        f"<p>frontier cluster <code>{html.escape(summary.get('frontierClusterRangeHex') or '-')}</code> {html.escape(summary.get('frontierClusterClass') or '-')}</p>",
        f"<p>proof found <code>{summary['proofFound']}</code>; failed current-root frontier gates <code>{html.escape(','.join(summary['failedCurrentRootFrontierGateIds']))}</code>; missing evidence <code>{len(summary['missingEvidence'])}</code>; evidence refs <code>{summary.get('evidenceRefCount')}</code></p>",
        f"<p>{html.escape(summary['conclusion'])}</p>",
        "<h2>Missing Evidence</h2>",
        "<ul>",
        "\n".join(f"<li>{html.escape(item)}</li>" for item in summary["missingEvidence"]),
        "</ul>",
        "<table><thead><tr><th>leaf</th><th>source?</th><th>target?</th><th>field maps</th><th>source tilesets</th><th>target tilesets</th><th>reader?</th><th>stop</th><th>nested</th></tr></thead><tbody>",
        rows,
        "</tbody></table>",
    ])


def write_outputs(summary: dict, out_dir: Path) -> None:
    out_dir.mkdir(parents=True, exist_ok=True)
    (out_dir / "save_selector_current_root_frontier_paths.json").write_text(
        json.dumps(summary, ensure_ascii=False, indent=2) + "\n",
        encoding="utf-8",
    )


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--references", type=Path, default=OUT / "save_scene_selector_references.json")
    parser.add_argument("--leaf-streams", type=Path, default=OUT / "save_selector_leaf_streams.json")
    parser.add_argument("--stream-traces", type=Path, default=OUT / "save_selector_stream_traces.json")
    parser.add_argument("--hotspot-gap", type=Path, default=OUT / "map1_01a_hotspot_gap.json")
    parser.add_argument("--field-roots", type=Path, default=OUT / "field_map_record_roots.json")
    parser.add_argument("--out-dir", type=Path, default=OUT)
    args = parser.parse_args()
    summary = build_summary(
        json.loads(args.references.read_text(encoding="utf-8")),
        json.loads(args.leaf_streams.read_text(encoding="utf-8")),
        json.loads(args.stream_traces.read_text(encoding="utf-8")),
        json.loads(args.hotspot_gap.read_text(encoding="utf-8")),
        json.loads(args.field_roots.read_text(encoding="utf-8")),
    )
    write_outputs(summary, args.out_dir)
    print(f"wrote current root frontier paths -> {args.out_dir / 'save_selector_current_root_frontier_paths.json'}")


if __name__ == "__main__":
    main()
