#!/usr/bin/env python3
"""Review direct pre-entry references to route-relevant selector roots.

The selected-root consumer and opcode 0x4f selector-byte writer are already
grounded separately.  This pass asks a narrower static question:

Can any direct pointer/reference prove who enters a root-local opcode 0x4f
self-writer, or who selects the current route root before the consumer runs?

It deliberately separates selector-table root-start references from stronger
pre-entry execution proof.
"""
from __future__ import annotations

import argparse
import html
import json
import struct
import sys
from pathlib import Path
from typing import Any

sys.path.insert(0, str(Path(__file__).resolve().parent))

from probe_exe_scene_tables import offset_to_va, read_sections  # noqa: E402


ROOT = Path(__file__).resolve().parents[1]
EXE = ROOT / "Hwanse2.exe"
OUT = ROOT / "out"
PROMOTION_STATUS = "selector-root-preentry-reference-blocked"
CURRENT_SELECTOR = "2:0"
SOURCE_OR_PREDECESSOR_SELECTORS = {"0:0", "1:0"}
ADDRESS_PREDECESSOR_SELECTOR = "10:0"


def hx(value: int | None) -> str:
    if value is None:
        return ""
    return f"0x{value:08x}"


def parse_hex(value: str | None) -> int | None:
    if not value:
        return None
    return int(value, 16)


def load_json(path: Path, fallback: Any) -> Any:
    if not path.exists():
        return fallback
    return json.loads(path.read_text(encoding="utf-8"))


def write_json(path: Path, payload: Any) -> None:
    path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


def write_text(path: Path, text: str) -> None:
    path.write_text(text, encoding="utf-8")


def h(value: Any) -> str:
    return html.escape("" if value is None else str(value))


def section_for_va(sections: list[dict[str, Any]], va: int | None) -> str:
    if va is None:
        return "file"
    for section in sections:
        if section["va"] <= va < section["va"] + section["raw_size"]:
            return str(section["name"])
    return "file"


def route_rows(runtime_selector_writes: dict[str, Any]) -> list[dict[str, Any]]:
    pattern = ((runtime_selector_writes.get("opcode4fDataScan") or {}).get("rootSelfWritePattern") or {})
    rows = pattern.get("routeContextSelfWriteRows") or []
    return [row for row in rows if row.get("rootContext")]


def selector_ranges(rows: list[dict[str, Any]]) -> dict[str, tuple[int, int]]:
    ranges: dict[str, tuple[int, int]] = {}
    for row in rows:
        context = row.get("rootContext") or {}
        selector = context.get("selector")
        root_range = context.get("rootRangeHex") or ""
        if not selector or ".." not in root_range:
            continue
        start, end = root_range.split("..", 1)
        ranges[str(selector)] = (int(start, 16), int(end, 16))
    return ranges


def selector_for_ref_va(ranges: dict[str, tuple[int, int]], va: int | None) -> str | None:
    if va is None:
        return None
    for selector, (start, end) in ranges.items():
        if start <= va < end:
            return selector
    return None


def exact_dword_refs(exe: bytes, sections: list[dict[str, Any]], value: int, ranges: dict[str, tuple[int, int]]) -> list[dict[str, Any]]:
    rows: list[dict[str, Any]] = []
    pattern = struct.pack("<I", value)
    offset = 0
    while True:
        hit = exe.find(pattern, offset)
        if hit < 0:
            break
        va = offset_to_va(sections, hit)
        rows.append(
            {
                "fileOffsetHex": hx(hit),
                "refVaHex": hx(va),
                "section": section_for_va(sections, va),
                "refSelector": selector_for_ref_va(ranges, va),
            }
        )
        offset = hit + 1
    return rows


def selected_pointer_va_by_selector(selectors: list[dict[str, Any]]) -> dict[str, str]:
    rows: dict[str, str] = {}
    for selector in selectors:
        key = f"{selector.get('group')}:{selector.get('slot')}"
        va = selector.get("selectedPointerVaHex")
        if va:
            rows[key] = str(va)
    return rows


def add_target_label(labels: dict[int, set[str]], value: str | None, label: str) -> None:
    parsed = parse_hex(value)
    if parsed is not None:
        labels.setdefault(parsed, set()).add(label)


def known_current_target_labels(
    runtime_selector_writes: dict[str, Any],
    prompt_owner_audit: dict[str, Any],
    active_object_inventory: dict[str, Any],
    active_initializer_review: dict[str, Any],
    active_target_audit: dict[str, Any],
) -> dict[int, set[str]]:
    labels: dict[int, set[str]] = {}

    root_pattern = ((runtime_selector_writes.get("opcode4fDataScan") or {}).get("rootSelfWritePattern") or {})
    for row in root_pattern.get("routeContextSelfWriteRows") or []:
        context = row.get("rootContext") or {}
        selector = context.get("selector")
        add_target_label(labels, context.get("rootHex"), f"{selector}-root-start")
        add_target_label(labels, row.get("vaHex"), f"{selector}-opcode4f-self-writer")

    for row in prompt_owner_audit.get("rows") or []:
        add_target_label(labels, row.get("scriptVaHex"), "opcode2f-script")
        for command in row.get("opcode2fCommands") or []:
            add_target_label(labels, command.get("commandVaHex"), "opcode2f-command")

    for row in active_object_inventory.get("inventory") or []:
        add_target_label(labels, row.get("initializerVaHex"), "active-object-initializer")
        add_target_label(labels, row.get("scriptVaHex"), "active-object-script")
    for row in active_object_inventory.get("scripts") or []:
        add_target_label(labels, row.get("scriptVaHex"), "active-object-script")
        for command in row.get("firstCommands") or []:
            add_target_label(labels, command.get("vaHex"), "active-object-first-command")

    for row in active_initializer_review.get("initializerRefRows") or []:
        add_target_label(labels, row.get("initializerVaHex"), "selected-root-initializer")
        add_target_label(labels, row.get("scriptVaHex"), "selected-root-initializer-script")
    for row in active_target_audit.get("rows") or []:
        for key, label in [
            ("rawTargetVaHex", "0307-raw-target"),
            ("targetEntryVaHex", "0307-target-entry"),
            ("scriptVaHex", "0307-script"),
            ("choiceEntryVaHex", "0307-choice-entry"),
        ]:
            add_target_label(labels, row.get(key), label)

    return labels


def classify_address_predecessor_bridge_row(
    row: dict[str, Any],
    *,
    current_selector_table_ref: str | None,
) -> str:
    if current_selector_table_ref and row.get("refVaHex") == current_selector_table_ref:
        return "selector-table-current-root-cell"
    if row.get("previousDwordHex") == "0x00000307":
        return "tagged-0307-current-range-entry"
    if row.get("previousDwordHex") == "0x0000005a" and row.get("nextDwordHex") == "0x0000034b":
        return "descriptor-0x5a-then-0x034b-current-range-entry"
    if row.get("previousDwordHex") == "0x00000004":
        if row.get("targetFirstOpcodeHex") == "0x6d":
            return "opcode04-to-object-script-entry"
        if row.get("targetFirstOpcodeHex") == "0x01":
            return "opcode04-to-display-continuation"
        return "opcode04-current-subentry-reference"
    if row.get("targetFirstOpcodeHex") == "0x31":
        return "flag-write-current-range-entry"
    if row.get("targetFirstOpcodeHex") == "0x32":
        return "flag-branch-current-range-entry"
    return "unclassified-address-predecessor-current-range-ref"


def scan_address_predecessor_current_bridge(
    exe: bytes,
    sections: list[dict[str, Any]],
    ranges: dict[str, tuple[int, int]],
    selector_table_refs: dict[str, str],
    target_labels: dict[int, set[str]],
    *,
    sample_limit: int = 14,
) -> dict[str, Any]:
    predecessor_range = ranges.get(ADDRESS_PREDECESSOR_SELECTOR)
    current_range = ranges.get(CURRENT_SELECTOR)
    if not predecessor_range or not current_range:
        return {
            "status": "missing-range",
            "rowCount": 0,
            "classificationCounts": {},
            "knownTargetLabelCounts": {},
            "rows": [],
            "samplesByClassification": {},
        }

    predecessor_start, predecessor_end = predecessor_range
    current_start, current_end = current_range
    current_selector_table_ref = selector_table_refs.get(CURRENT_SELECTOR)
    rows: list[dict[str, Any]] = []
    classification_counts: dict[str, int] = {}
    label_counts: dict[str, int] = {}
    samples_by_classification: dict[str, list[dict[str, Any]]] = {}

    for offset in range(0, len(exe) - 3, 4):
        target = struct.unpack_from("<I", exe, offset)[0]
        if not (current_start <= target < current_end):
            continue
        ref_va = offset_to_va(sections, offset)
        if not (predecessor_start <= ref_va < predecessor_end):
            continue
        previous_dword = struct.unpack_from("<I", exe, offset - 4)[0] if offset >= 4 else None
        previous2_dword = struct.unpack_from("<I", exe, offset - 8)[0] if offset >= 8 else None
        next_dword = struct.unpack_from("<I", exe, offset + 4)[0] if offset + 4 <= len(exe) - 4 else None
        target_offset = None
        target_first_opcode = None
        target_first_dword = None
        target_actual_opcode_role = ""
        target_branch_target = None
        target_fallthrough = None
        for section in sections:
            if section["va"] <= target < section["va"] + section["raw_size"]:
                target_offset = section["raw"] + (target - section["va"])
                break
        if target_offset is not None and 0 <= target_offset < len(exe):
            target_first_opcode = exe[target_offset]
            if target_offset + 4 <= len(exe):
                target_first_dword = struct.unpack_from("<I", exe, target_offset)[0]
            if target_first_opcode == 0x31:
                target_actual_opcode_role = "actual-dispatcher-flag-write"
                target_fallthrough = target + 4
            elif target_first_opcode == 0x32 and target_offset + 8 <= len(exe):
                target_actual_opcode_role = "actual-dispatcher-flag-branch"
                target_branch_target = struct.unpack_from("<I", exe, target_offset + 4)[0]
                target_fallthrough = target + 8
        labels = sorted(target_labels.get(target, set()))
        row = {
            "refVaHex": hx(ref_va),
            "fileOffsetHex": hx(offset),
            "targetValueHex": hx(target),
            "targetOffsetHex": f"+0x{target - current_start:03x}",
            "targetFirstOpcodeHex": f"0x{target_first_opcode:02x}" if target_first_opcode is not None else "",
            "targetFirstDwordHex": hx(target_first_dword),
            "targetActualOpcodeRole": target_actual_opcode_role,
            "targetBranchTargetHex": hx(target_branch_target),
            "targetFallthroughHex": hx(target_fallthrough),
            "previous2DwordHex": hx(previous2_dword),
            "previousDwordHex": hx(previous_dword),
            "nextDwordHex": hx(next_dword),
            "knownTargetLabels": labels,
        }
        row["classification"] = classify_address_predecessor_bridge_row(
            row,
            current_selector_table_ref=current_selector_table_ref,
        )
        rows.append(row)
        classification = row["classification"]
        classification_counts[classification] = classification_counts.get(classification, 0) + 1
        samples = samples_by_classification.setdefault(classification, [])
        if len(samples) < sample_limit:
            samples.append(row)
        for label in labels:
            label_counts[label] = label_counts.get(label, 0) + 1

    return {
        "status": "classified",
        "addressPredecessorSelector": ADDRESS_PREDECESSOR_SELECTOR,
        "addressPredecessorRangeHex": f"{hx(predecessor_start)}..{hx(predecessor_end)}",
        "currentSelector": CURRENT_SELECTOR,
        "currentRangeHex": f"{hx(current_start)}..{hx(current_end)}",
        "currentSelectorTableRefVaHex": current_selector_table_ref,
        "rowCount": len(rows),
        "classificationCounts": classification_counts,
        "knownTargetLabelCounts": label_counts,
        "routeExecutionProofFound": False,
        "conclusion": (
            "The 10:0 -> 2:0 bridge is real as a data-structure bridge, but its rows resolve to selector-table, "
            "0x0307 initializer-list, 0x5a/0x034b descriptor packet, opcode04-style subentry references, "
            "and actual-dispatcher opcode31/32 flag-write/flag-branch subentries. "
            "No row is promoted to a concrete route execution producer without a scheduler/consumer path."
        ),
        "rows": rows,
        "samplesByClassification": samples_by_classification,
    }


def annotate_root_refs(refs: list[dict[str, Any]], selector: str, selector_table_refs: dict[str, str]) -> list[dict[str, Any]]:
    selector_table_ref = selector_table_refs.get(selector)
    rows = []
    for ref in refs:
        role = "other"
        if selector_table_ref and ref.get("refVaHex") == selector_table_ref:
            role = "selector-table-selected-pointer"
        elif ref.get("section") == ".text":
            role = "text-direct-reference"
        elif ref.get("refSelector") == selector:
            role = "same-root-reference"
        elif ref.get("refSelector"):
            role = "other-root-reference"
        elif ref.get("section") == ".data":
            role = "external-data-reference"
        rows.append({**ref, "role": role})
    return rows


def scan_range_refs(
    exe: bytes,
    sections: list[dict[str, Any]],
    target_selector: str,
    target_start: int,
    target_end: int,
    ranges: dict[str, tuple[int, int]],
    *,
    sample_limit: int = 24,
) -> dict[str, Any]:
    counts: dict[str, int] = {}
    section_counts: dict[str, int] = {}
    source_or_predecessor_samples: list[dict[str, Any]] = []
    external_samples: list[dict[str, Any]] = []

    for offset in range(0, len(exe) - 3, 4):
        value = struct.unpack_from("<I", exe, offset)[0]
        if not (target_start <= value < target_end):
            continue
        va = offset_to_va(sections, offset)
        section = section_for_va(sections, va)
        ref_selector = selector_for_ref_va(ranges, va)
        bucket = ref_selector or f"{section}:external"
        counts[bucket] = counts.get(bucket, 0) + 1
        section_counts[section] = section_counts.get(section, 0) + 1
        row = {
            "refVaHex": hx(va),
            "fileOffsetHex": hx(offset),
            "section": section,
            "refSelector": ref_selector,
            "targetSelector": target_selector,
            "targetValueHex": hx(value),
            "targetOffsetHex": f"+0x{value - target_start:03x}",
        }
        if ref_selector in SOURCE_OR_PREDECESSOR_SELECTORS and target_selector == CURRENT_SELECTOR:
            if len(source_or_predecessor_samples) < sample_limit:
                source_or_predecessor_samples.append(row)
        elif ref_selector != target_selector:
            if len(external_samples) < sample_limit:
                external_samples.append(row)

    return {
        "targetSelector": target_selector,
        "targetRangeHex": f"{hx(target_start)}..{hx(target_end)}",
        "totalAlignedRangeRefCount": sum(counts.values()),
        "countsByRefContext": counts,
        "countsBySection": section_counts,
        "sourceOrPredecessorToCurrentRangeRefCount": sum(
            count
            for context, count in counts.items()
            if target_selector == CURRENT_SELECTOR and context in SOURCE_OR_PREDECESSOR_SELECTORS
        ),
        "textRangeRefCount": section_counts.get(".text", 0),
        "externalSamples": external_samples,
        "sourceOrPredecessorToCurrentSamples": source_or_predecessor_samples,
    }


def build(args: argparse.Namespace) -> dict[str, Any]:
    exe = args.exe.read_bytes()
    sections = read_sections(exe)
    selectors = load_json(args.selectors, [])
    runtime_selector_writes = load_json(args.runtime_selector_writes, {})
    prompt_owner_audit = load_json(OUT / "opcode2f_prompt_stream_owner_audit.json", {})
    active_object_inventory = load_json(OUT / "active_object_script_inventory.json", {})
    active_initializer_review = load_json(OUT / "selected_root_active_object_initializer_ref_review.json", {})
    active_target_audit = load_json(OUT / "scene_0307_active_object_target_audit.json", {})
    rows = route_rows(runtime_selector_writes)
    ranges = selector_ranges(rows)
    selector_table_refs = selected_pointer_va_by_selector(selectors)
    target_labels = known_current_target_labels(
        runtime_selector_writes,
        prompt_owner_audit,
        active_object_inventory,
        active_initializer_review,
        active_target_audit,
    )

    root_reviews = []
    exact_self_writer_ref_count = 0
    exact_root_text_ref_count = 0
    selector_table_only_root_ref_count = 0

    for row in rows:
        context = row.get("rootContext") or {}
        selector = str(context.get("selector"))
        root_hex = str(context.get("rootHex"))
        writer_hex = str(row.get("vaHex"))
        root_va = int(root_hex, 16)
        writer_va = int(writer_hex, 16)
        root_refs = annotate_root_refs(exact_dword_refs(exe, sections, root_va, ranges), selector, selector_table_refs)
        writer_refs = exact_dword_refs(exe, sections, writer_va, ranges)
        exact_self_writer_ref_count += len(writer_refs)
        exact_root_text_ref_count += sum(1 for ref in root_refs if ref.get("section") == ".text")
        selector_table_only_root_ref_count += 1 if root_refs and all(ref.get("role") == "selector-table-selected-pointer" for ref in root_refs) else 0
        root_reviews.append(
            {
                "selector": selector,
                "rootHex": root_hex,
                "rootRangeHex": context.get("rootRangeHex"),
                "selfWriterVaHex": writer_hex,
                "selfWriterValueHex": row.get("valueHex"),
                "routeRole": row.get("routeRole"),
                "selfWriterOffsetHex": context.get("relativeOffsetHex"),
                "rootExactRefCount": len(root_refs),
                "rootExactTextRefCount": sum(1 for ref in root_refs if ref.get("section") == ".text"),
                "rootRefs": root_refs,
                "selfWriterExactRefCount": len(writer_refs),
                "selfWriterExactTextRefCount": sum(1 for ref in writer_refs if ref.get("section") == ".text"),
                "selfWriterRefs": writer_refs,
                "selectorTableRefVaHex": selector_table_refs.get(selector),
            }
        )

    range_reviews = [
        scan_range_refs(exe, sections, selector, start, end, ranges)
        for selector, (start, end) in ranges.items()
    ]
    current_range_review = next((row for row in range_reviews if row["targetSelector"] == CURRENT_SELECTOR), {})
    current_counts = current_range_review.get("countsByRefContext", {}) or {}
    address_predecessor_to_current_count = current_counts.get(ADDRESS_PREDECESSOR_SELECTOR, 0)
    address_predecessor_bridge = scan_address_predecessor_current_bridge(
        exe,
        sections,
        ranges,
        selector_table_refs,
        target_labels,
    )

    summary = {
        "kind": "hwanse-selector-root-preentry-ref-review",
        "promotionStatus": PROMOTION_STATUS,
        "routeSelfWriterRowCount": len(rows),
        "routeSelectors": [row["selector"] for row in root_reviews],
        "exactSelfWriterRefCount": exact_self_writer_ref_count,
        "exactRootTextRefCount": exact_root_text_ref_count,
        "selectorTableOnlyRootRefCount": selector_table_only_root_ref_count,
        "currentSelector": CURRENT_SELECTOR,
        "currentRangeTextRefCount": current_range_review.get("textRangeRefCount", 0),
        "sourceOrPredecessorToCurrentRangeRefCount": current_range_review.get("sourceOrPredecessorToCurrentRangeRefCount", 0),
        "addressPredecessorSelector": ADDRESS_PREDECESSOR_SELECTOR,
        "addressPredecessorToCurrentRangeRefCount": address_predecessor_to_current_count,
        "addressPredecessorBridgeClassificationCounts": address_predecessor_bridge.get("classificationCounts", {}),
        "addressPredecessorBridgeRouteExecutionProofFound": address_predecessor_bridge.get("routeExecutionProofFound", False),
        "preEntryProducerProofFound": False,
        "rootLocalSelfWriterEntryProofFound": exact_self_writer_ref_count > 0,
        "routePromotionBlockedReason": (
            "Route-relevant root starts are directly referenced only through selector-table selected-pointer cells, "
            "and root-local opcode 0x4f self-writer addresses have no direct dword references. "
            "No source/predecessor root contains an aligned pointer into the current selector 2:0 range. "
            "Address-predecessor selector 10:0 does contain current-range pointers, so that bridge is the next "
            "static candidate, but it is not source/predecessor route proof by itself."
        ),
    }
    return {
        **summary,
        "rootReviews": root_reviews,
        "rangeReviews": range_reviews,
        "addressPredecessorBridge": address_predecessor_bridge,
        "remainingProofs": [
            "find a pre-entry command that writes selected root 0x00540714 into 0x0059de30",
            "find a strict source/predecessor reference into the current selector 2:0 root/range",
            "capture runtime selected-root consumer state at 0x0040adfe",
            "prove a normal control path from a source hotspot to the current root consumer",
        ],
    }


def markdown(payload: dict[str, Any]) -> str:
    lines = [
        "# Selector Root Pre-entry Reference Review",
        "",
        f"- promotion status: `{payload['promotionStatus']}`",
        f"- route self-writer rows: {payload['routeSelfWriterRowCount']}",
        f"- exact self-writer dword refs: {payload['exactSelfWriterRefCount']}",
        f"- exact root text refs: {payload['exactRootTextRefCount']}",
        f"- selector-table-only root refs: {payload['selectorTableOnlyRootRefCount']}",
        f"- current range text refs: {payload['currentRangeTextRefCount']}",
        f"- source/predecessor -> current range refs: {payload['sourceOrPredecessorToCurrentRangeRefCount']}",
        f"- address-predecessor `{payload['addressPredecessorSelector']}` -> current range refs: {payload['addressPredecessorToCurrentRangeRefCount']}",
        f"- address-predecessor bridge route execution proof: {payload['addressPredecessorBridgeRouteExecutionProofFound']}",
        f"- address-predecessor bridge classes: `{payload['addressPredecessorBridgeClassificationCounts']}`",
        f"- pre-entry producer proof found: {payload['preEntryProducerProofFound']}",
        "",
        payload["routePromotionBlockedReason"],
        "",
        "## Root Exact References",
        "",
        "| selector | root | self-writer | root refs | root text refs | self-writer refs | selector table cell | role |",
        "| --- | --- | --- | ---: | ---: | ---: | --- | --- |",
    ]
    for row in payload["rootReviews"]:
        roles = ", ".join(sorted({ref.get("role", "") for ref in row.get("rootRefs") or []})) or "-"
        lines.append(
            f"| `{row['selector']}` | `{row['rootHex']}` | `{row['selfWriterVaHex']}` | "
            f"{row['rootExactRefCount']} | {row['rootExactTextRefCount']} | {row['selfWriterExactRefCount']} | "
            f"`{row.get('selectorTableRefVaHex') or '-'}` | {roles} |"
        )
    lines.extend([
        "",
        "## Range Reference Summary",
        "",
        "| target selector | range | total aligned refs | text refs | source/predecessor -> current refs | counts by context |",
        "| --- | --- | ---: | ---: | ---: | --- |",
    ])
    for row in payload["rangeReviews"]:
        counts = ", ".join(f"{key}:{value}" for key, value in sorted(row.get("countsByRefContext", {}).items()))
        lines.append(
            f"| `{row['targetSelector']}` | `{row['targetRangeHex']}` | {row['totalAlignedRangeRefCount']} | "
            f"{row['textRangeRefCount']} | {row['sourceOrPredecessorToCurrentRangeRefCount']} | {counts or '-'} |"
        )
    lines.extend(["", "## Current Range External Samples", ""])
    current = next((row for row in payload["rangeReviews"] if row["targetSelector"] == CURRENT_SELECTOR), {})
    lines.extend(["| ref | section | ref selector | target value | target offset |", "| --- | --- | --- | --- | --- |"])
    for row in current.get("externalSamples") or []:
        lines.append(
            f"| `{row['refVaHex']}` | {row['section']} | `{row.get('refSelector') or '-'}` | "
            f"`{row['targetValueHex']}` | `{row['targetOffsetHex']}` |"
        )
    bridge = payload.get("addressPredecessorBridge") or {}
    lines.extend([
        "",
        "## Address-Predecessor Bridge Classification",
        "",
        bridge.get("conclusion") or "",
        "",
        "| class | count |",
        "| --- | ---: |",
    ])
    for key, value in sorted((bridge.get("classificationCounts") or {}).items()):
        lines.append(f"| `{key}` | {value} |")
    lines.extend([
        "",
        "### Bridge Samples",
        "",
        "| class | ref | target | offset | target first opcode | actual role | branch target | fallthrough | previous | next | known target labels |",
        "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |",
    ])
    for key, samples in sorted((bridge.get("samplesByClassification") or {}).items()):
        for row in samples:
            labels = ", ".join(row.get("knownTargetLabels") or []) or "-"
            lines.append(
                f"| `{key}` | `{row['refVaHex']}` | `{row['targetValueHex']}` | `{row['targetOffsetHex']}` | "
                f"`{row.get('targetFirstOpcodeHex') or '-'}` | {row.get('targetActualOpcodeRole') or '-'} | "
                f"`{row.get('targetBranchTargetHex') or '-'}` | "
                f"`{row.get('targetFallthroughHex') or '-'}` | `{row['previousDwordHex']}` | "
                f"`{row['nextDwordHex']}` | {labels} |"
            )
    lines.extend(["", "## Remaining Proofs", ""])
    lines.extend(f"- {item}" for item in payload["remainingProofs"])
    lines.append("")
    return "\n".join(lines)


def html_page(payload: dict[str, Any]) -> str:
    root_rows = "\n".join(
        "<tr>"
        f"<td><code>{h(row['selector'])}</code></td>"
        f"<td><code>{h(row['rootHex'])}</code></td>"
        f"<td><code>{h(row['selfWriterVaHex'])}</code></td>"
        f"<td>{row['rootExactRefCount']}</td>"
        f"<td>{row['rootExactTextRefCount']}</td>"
        f"<td>{row['selfWriterExactRefCount']}</td>"
        f"<td><code>{h(row.get('selectorTableRefVaHex') or '-')}</code></td>"
        f"<td>{h(', '.join(sorted({ref.get('role', '') for ref in row.get('rootRefs') or []})) or '-')}</td>"
        "</tr>"
        for row in payload["rootReviews"]
    )
    range_rows = "\n".join(
        "<tr>"
        f"<td><code>{h(row['targetSelector'])}</code></td>"
        f"<td><code>{h(row['targetRangeHex'])}</code></td>"
        f"<td>{row['totalAlignedRangeRefCount']}</td>"
        f"<td>{row['textRangeRefCount']}</td>"
        f"<td>{row['sourceOrPredecessorToCurrentRangeRefCount']}</td>"
        f"<td>{h(', '.join(f'{k}:{v}' for k, v in sorted(row.get('countsByRefContext', {}).items())) or '-')}</td>"
        "</tr>"
        for row in payload["rangeReviews"]
    )
    current = next((row for row in payload["rangeReviews"] if row["targetSelector"] == CURRENT_SELECTOR), {})
    sample_rows = "\n".join(
        "<tr>"
        f"<td><code>{h(row['refVaHex'])}</code></td>"
        f"<td>{h(row['section'])}</td>"
        f"<td><code>{h(row.get('refSelector') or '-')}</code></td>"
        f"<td><code>{h(row['targetValueHex'])}</code></td>"
        f"<td><code>{h(row['targetOffsetHex'])}</code></td>"
        "</tr>"
        for row in current.get("externalSamples") or []
    )
    bridge = payload.get("addressPredecessorBridge") or {}
    bridge_count_rows = "\n".join(
        "<tr>"
        f"<td><code>{h(key)}</code></td>"
        f"<td>{value}</td>"
        "</tr>"
        for key, value in sorted((bridge.get("classificationCounts") or {}).items())
    )
    bridge_sample_rows = "\n".join(
        "<tr>"
        f"<td><code>{h(classification)}</code></td>"
        f"<td><code>{h(row['refVaHex'])}</code></td>"
        f"<td><code>{h(row['targetValueHex'])}</code></td>"
        f"<td><code>{h(row['targetOffsetHex'])}</code></td>"
        f"<td><code>{h(row.get('targetFirstOpcodeHex') or '-')}</code></td>"
        f"<td>{h(row.get('targetActualOpcodeRole') or '-')}</td>"
        f"<td><code>{h(row.get('targetBranchTargetHex') or '-')}</code></td>"
        f"<td><code>{h(row.get('targetFallthroughHex') or '-')}</code></td>"
        f"<td><code>{h(row['previousDwordHex'])}</code></td>"
        f"<td><code>{h(row['nextDwordHex'])}</code></td>"
        f"<td>{h(', '.join(row.get('knownTargetLabels') or []) or '-')}</td>"
        "</tr>"
        for classification, samples in sorted((bridge.get("samplesByClassification") or {}).items())
        for row in samples
    )
    return f"""<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Selector Root Pre-entry Reference Review</title>
  <style>
    body {{ margin: 24px; background: #101010; color: #eee; font: 14px system-ui, sans-serif; }}
    table {{ border-collapse: collapse; width: 100%; margin: 16px 0 28px; }}
    th, td {{ border: 1px solid #333; padding: 6px 8px; vertical-align: top; }}
    th {{ background: #1d1d1d; position: sticky; top: 0; }}
    code {{ color: #f5d76e; }}
    .warn {{ color: #ffd166; }}
  </style>
</head>
<body>
  <h1>Selector Root Pre-entry Reference Review</h1>
  <p class="warn">promotion status: <code>{h(payload['promotionStatus'])}</code></p>
  <p>{h(payload['routePromotionBlockedReason'])}</p>
  <ul>
    <li>route self-writer rows: {payload['routeSelfWriterRowCount']}</li>
    <li>exact self-writer dword refs: {payload['exactSelfWriterRefCount']}</li>
    <li>exact root text refs: {payload['exactRootTextRefCount']}</li>
    <li>selector-table-only root refs: {payload['selectorTableOnlyRootRefCount']}</li>
    <li>current range text refs: {payload['currentRangeTextRefCount']}</li>
    <li>source/predecessor -&gt; current range refs: {payload['sourceOrPredecessorToCurrentRangeRefCount']}</li>
    <li>address-predecessor <code>{h(payload['addressPredecessorSelector'])}</code> -&gt; current range refs: {payload['addressPredecessorToCurrentRangeRefCount']}</li>
    <li>address-predecessor bridge route execution proof: {payload['addressPredecessorBridgeRouteExecutionProofFound']}</li>
  </ul>
  <h2>Root Exact References</h2>
  <table><thead><tr><th>selector</th><th>root</th><th>self-writer</th><th>root refs</th><th>root text refs</th><th>self-writer refs</th><th>selector table cell</th><th>root ref roles</th></tr></thead><tbody>
{root_rows}
  </tbody></table>
  <h2>Range Reference Summary</h2>
  <table><thead><tr><th>target selector</th><th>range</th><th>total aligned refs</th><th>text refs</th><th>source/predecessor -&gt; current refs</th><th>counts by context</th></tr></thead><tbody>
{range_rows}
  </tbody></table>
  <h2>Current Range External Samples</h2>
  <table><thead><tr><th>ref</th><th>section</th><th>ref selector</th><th>target value</th><th>target offset</th></tr></thead><tbody>
{sample_rows}
  </tbody></table>
  <h2>Address-Predecessor Bridge Classification</h2>
  <p>{h(bridge.get('conclusion') or '')}</p>
  <table><thead><tr><th>classification</th><th>count</th></tr></thead><tbody>
{bridge_count_rows}
  </tbody></table>
  <table><thead><tr><th>classification</th><th>ref</th><th>target</th><th>offset</th><th>target first opcode</th><th>actual role</th><th>branch target</th><th>fallthrough</th><th>previous</th><th>next</th><th>known target labels</th></tr></thead><tbody>
{bridge_sample_rows}
  </tbody></table>
</body>
</html>
"""


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--exe", type=Path, default=EXE)
    parser.add_argument("--selectors", type=Path, default=OUT / "save_scene_selectors.json")
    parser.add_argument("--runtime-selector-writes", type=Path, default=OUT / "save_selector_runtime_selector_byte_writes.json")
    parser.add_argument("--json-out", type=Path, default=OUT / "selector_root_preentry_ref_review.json")
    parser.add_argument("--md-out", type=Path, default=None, help="Optional markdown export path.")
    parser.add_argument("--html-out", type=Path, default=None)
    args = parser.parse_args()

    payload = build(args)
    write_json(args.json_out, payload)
    if args.md_out:
        write_text(args.md_out, markdown(payload))
    if args.html_out:
        write_text(args.html_out, html_page(payload))
        print(f"wrote {args.json_out}, {args.html_out}")
    else:
        print(f"wrote {args.json_out}")


if __name__ == "__main__":
    main()
