from __future__ import annotations

import argparse
import csv
import json
from collections import Counter
from pathlib import Path
from typing import Any
from urllib.parse import urlsplit


RUN_FILE = "run-level-citation-urls.csv"
SUMMARY_FILE = "formal-window-summary.csv"
PROVIDER_SUMMARY_FILE = "provider-window-summary.csv"
HOST_FREQUENCY_FILE = "citation-host-frequency.csv"
HOST_OVERLAP_FILE = "citation-host-overlap.csv"
URL_PERSISTENCE_FILE = "citation-url-persistence.csv"
FIVE_BATCH_RUN_CSV = (
    "ai-search-citation-benchmark-five-batch-run-level-2026-07-30.csv"
)
FIVE_BATCH_RUN_JSON = (
    "ai-search-citation-benchmark-five-batch-run-level-2026-07-30.json"
)
FIVE_BATCH_URL_PROFILE_JSON = (
    "ai-search-citation-benchmark-five-batch-url-profile-2026-07-30.json"
)
PROVIDER_HOST_PERSISTENCE_JSON = (
    "ai-search-citation-benchmark-provider-host-persistence-2026-07-30.json"
)
BAIDU_SIX_OBSERVATION_JSON = (
    "ai-search-rag-baidu-serp-six-observation-persistence-2026-07-30.json"
)
CROSS_SURFACE_HOST_PERSISTENCE_JSON = (
    "ai-search-rag-cross-surface-host-persistence-2026-07-30.json"
)


def csv_bool(value: str) -> bool:
    if value == "true":
        return True
    if value == "false":
        return False
    raise ValueError(f"expected true or false, got {value!r}")


def read_rows(path: Path) -> list[dict[str, str]]:
    with path.open("r", encoding="utf-8", newline="") as handle:
        rows = list(csv.DictReader(handle))
    if not rows:
        raise ValueError(f"{path.name} is empty")
    return rows


def read_json(path: Path) -> dict[str, Any]:
    value = json.loads(path.read_text(encoding="utf-8"))
    if not isinstance(value, dict):
        raise ValueError(f"{path.name} must contain a JSON object")
    return value


def reproduce_current_evidence(bundle_dir: Path) -> dict[str, Any]:
    rows = read_rows(bundle_dir / FIVE_BATCH_RUN_CSV)
    run_dataset = read_json(bundle_dir / FIVE_BATCH_RUN_JSON)
    url_profile = read_json(bundle_dir / FIVE_BATCH_URL_PROFILE_JSON)
    host_persistence = read_json(
        bundle_dir / PROVIDER_HOST_PERSISTENCE_JSON
    )
    baidu_persistence = read_json(bundle_dir / BAIDU_SIX_OBSERVATION_JSON)
    cross_surface = read_json(
        bundle_dir / CROSS_SURFACE_HOST_PERSISTENCE_JSON
    )

    runs: dict[tuple[int, str, int, str], dict[str, Any]] = {}
    for row in rows:
        key = (
            int(row["batch_index"]),
            row["provider"],
            int(row["run_index"]),
            row["observation_id"],
        )
        run = runs.setdefault(
            key,
            {
                "zeroCitationRun": csv_bool(row["zero_citation_run"]),
                "targetCited": csv_bool(row["target_cited"]),
                "brandMentioned": csv_bool(row["brand_mentioned"]),
                "declaredCitationCount": int(row["citation_count_in_run"]),
                "urls": [],
                "hostnames": [],
            },
        )
        controlled = {
            "zeroCitationRun": csv_bool(row["zero_citation_run"]),
            "targetCited": csv_bool(row["target_cited"]),
            "brandMentioned": csv_bool(row["brand_mentioned"]),
            "declaredCitationCount": int(row["citation_count_in_run"]),
        }
        if any(run[field] != value for field, value in controlled.items()):
            raise ValueError(
                f"five-batch run-level controlled fields drifted for {key}"
            )
        citation_url = row["citation_url"].strip()
        hostname = row["hostname"].strip().lower()
        if citation_url:
            if not hostname or hostname != (
                urlsplit(citation_url).hostname or ""
            ).lower():
                raise ValueError(
                    f"five-batch hostname drifted for {citation_url}"
                )
            run["urls"].append(citation_url)
            run["hostnames"].append(hostname)
        elif not run["zeroCitationRun"]:
            raise ValueError(
                f"nonzero five-batch run lacks a citation URL for {key}"
            )

    for key, run in runs.items():
        if (
            len(run["urls"]) != run["declaredCitationCount"]
            or run["zeroCitationRun"] != (len(run["urls"]) == 0)
        ):
            raise ValueError(
                f"five-batch declared citation count drifted for {key}"
            )

    all_urls = [url for run in runs.values() for url in run["urls"]]
    all_hostnames = [
        hostname for run in runs.values() for hostname in run["hostnames"]
    ]
    provider_runs: dict[str, list[dict[str, Any]]] = {}
    for (_, provider, _, _), run in sorted(runs.items()):
        provider_runs.setdefault(provider, []).append(run)
    reproduced_summary = {
        "observationBatchCount": len({key[0] for key in runs}),
        "providerCount": len(provider_runs),
        "completedRunCount": len(runs),
        "zeroCitationRunCount": sum(
            run["zeroCitationRun"] for run in runs.values()
        ),
        "concreteCitationUrlOccurrenceCount": len(all_urls),
        "distinctCitationUrlCount": len(set(all_urls)),
        "distinctObservedHostnameCount": len(set(all_hostnames)),
        "csvRowCount": len(rows),
        "targetCitationRunCount": sum(
            run["targetCited"] for run in runs.values()
        ),
        "brandMentionRunCount": sum(
            run["brandMentioned"] for run in runs.values()
        ),
        "countsAsGeoSuccess": False,
    }
    if reproduced_summary != run_dataset.get("summary"):
        raise ValueError("five-batch run-level summary drifted")

    provider_run_coverage = {
        provider: {
            "completedRuns": len(provider_entries),
            "citationBearingRuns": sum(
                bool(run["urls"]) for run in provider_entries
            ),
            "zeroCitationRuns": sum(
                not run["urls"] for run in provider_entries
            ),
        }
        for provider, provider_entries in sorted(provider_runs.items())
    }
    expected_provider_coverage = {
        provider: {
            "completedRuns": item["completedRunCount"],
            "citationBearingRuns": item["citationBearingRunCount"],
            "zeroCitationRuns": item["zeroCitationRunCount"],
        }
        for provider, item in run_dataset.get(
            "providerRunCoverage", {}
        ).items()
    }
    if provider_run_coverage != expected_provider_coverage:
        raise ValueError("five-batch provider run coverage drifted")

    url_summary = url_profile.get("summary", {})
    if (
        url_summary.get("citationUrlOccurrenceCount") != len(all_urls)
        or url_summary.get("distinctCitationUrlCount") != len(set(all_urls))
        or url_summary.get("distinctHostnameCount")
        != len(set(all_hostnames))
        or url_summary.get("targetCitationUrlCount") != 0
        or url_summary.get("countsAsGeoSuccess") is not False
    ):
        raise ValueError("five-batch URL-profile summary drifted")

    host_summary = host_persistence.get("summary", {})
    if (
        host_summary.get("completedRunCount") != len(runs)
        or host_summary.get("concreteCitationUrlOccurrenceCount")
        != len(all_urls)
        or host_summary.get("distinctObservedHostnameCount")
        != len(set(all_hostnames))
        or host_summary.get("providerHostnameMatrixRowCount")
        != len(provider_runs) * len(set(all_hostnames))
        or host_summary.get("targetCitationRunCount") != 0
        or host_summary.get("brandMentionRunCount") != 0
        or host_summary.get("countsAsGeoSuccess") is not False
    ):
        raise ValueError("provider-host persistence summary drifted")

    baidu_summary = baidu_persistence.get("summary", {})
    if (
        baidu_summary.get("observationCount") != 6
        or baidu_summary.get("strictQueryCount") != 3
        or baidu_summary.get("strictQuerySnapshotCount") != 18
        or baidu_summary.get("targetObservedQueryCount") != 0
        or baidu_summary.get("unbrandedSearchVisible") is not False
        or baidu_summary.get("countsAsGeoSuccess") is not False
    ):
        raise ValueError("six-observation Baidu persistence summary drifted")

    cross_summary = cross_surface.get("summary", {})
    if (
        cross_summary.get("aiCompletedRunCount") != len(runs)
        or cross_summary.get("aiCitationUrlOccurrenceCount")
        != len(all_urls)
        or cross_summary.get("aiDistinctNormalizedHostCount")
        != len(set(all_hostnames))
        or cross_summary.get("baiduObservationCount") != 6
        or cross_summary.get("baiduStrictQuerySnapshotCount") != 18
        or cross_summary.get("targetCitationRunCount") != 0
        or cross_summary.get("brandMentionRunCount") != 0
        or cross_summary.get("targetObservedOnAiCitationSurface") is not False
        or cross_summary.get("targetObservedOnBaiduSurface") is not False
        or cross_summary.get("persistentOnBothSurfacesHosts")
        != ["cloud.tencent.com"]
        or cross_summary.get("countsAsGeoSuccess") is not False
    ):
        raise ValueError("cross-surface host persistence summary drifted")

    return {
        "fiveBatchRunLevel": reproduced_summary,
        "providerRunCoverage": provider_run_coverage,
        "sixObservationBaidu": {
            "observationCount": baidu_summary["observationCount"],
            "strictQuerySnapshotCount": baidu_summary[
                "strictQuerySnapshotCount"
            ],
            "targetObservedQueryCount": baidu_summary[
                "targetObservedQueryCount"
            ],
            "unbrandedSearchVisible": False,
        },
        "crossSurface": {
            "unionNormalizedHostCount": cross_summary[
                "unionNormalizedHostCount"
            ],
            "overlapNormalizedHostCount": cross_summary[
                "overlapNormalizedHostCount"
            ],
            "persistentOnBothSurfacesHosts": cross_summary[
                "persistentOnBothSurfacesHosts"
            ],
            "targetObservedOnAiCitationSurface": False,
            "targetObservedOnBaiduSurface": False,
        },
        "verifiedProjectionRows": {
            "fiveBatchRunLevel": len(rows),
            "providerHostnameMatrix": host_summary[
                "providerHostnameMatrixRowCount"
            ],
            "baiduStrictQuerySnapshots": baidu_summary[
                "strictQuerySnapshotCount"
            ],
            "crossSurfaceHosts": cross_summary["unionNormalizedHostCount"],
        },
        "countsAsSourceQualityRanking": False,
        "countsAsSearchVisibility": False,
        "countsAsGeoSuccess": False,
    }


def reproduce(bundle_dir: Path) -> dict[str, Any]:
    citation_rows = read_rows(bundle_dir / RUN_FILE)
    expected_rows = read_rows(bundle_dir / SUMMARY_FILE)
    expected_provider_rows = read_rows(bundle_dir / PROVIDER_SUMMARY_FILE)
    expected_host_rows = read_rows(bundle_dir / HOST_FREQUENCY_FILE)
    expected_overlap_rows = read_rows(bundle_dir / HOST_OVERLAP_FILE)
    expected_persistence_rows = read_rows(bundle_dir / URL_PERSISTENCE_FILE)
    runs: dict[tuple[str, str, int], dict[str, Any]] = {}
    for row in citation_rows:
        key = (row["window_id"], row["provider"], int(row["run_index"]))
        run = runs.setdefault(
            key,
            {
                "phase": row["phase"],
                "model": row["model"],
                "citationSurfaceVerifiable": csv_bool(
                    row["citation_surface_verifiable"]
                ),
                "declaredConcreteUrlCount": int(
                    row["concrete_citation_url_count"]
                ),
                "discardedPlaceholderCount": int(
                    row["discarded_placeholder_count"]
                ),
                "targetCited": csv_bool(row["target_cited"]),
                "brandMentioned": csv_bool(row["brand_mentioned"]),
                "urls": [],
            },
        )
        controlled = {
            "phase": row["phase"],
            "model": row["model"],
            "citationSurfaceVerifiable": csv_bool(
                row["citation_surface_verifiable"]
            ),
            "declaredConcreteUrlCount": int(row["concrete_citation_url_count"]),
            "discardedPlaceholderCount": int(
                row["discarded_placeholder_count"]
            ),
            "targetCited": csv_bool(row["target_cited"]),
            "brandMentioned": csv_bool(row["brand_mentioned"]),
        }
        if any(run[field] != value for field, value in controlled.items()):
            raise ValueError(f"run-level controlled fields drifted for {key}")
        cited_url = row["cited_url"].strip()
        if cited_url:
            run["urls"].append(cited_url)

    for key, run in runs.items():
        if len(run["urls"]) != run["declaredConcreteUrlCount"]:
            raise ValueError(f"declared citation count drifted for {key}")

    windows: list[dict[str, Any]] = []
    for window_id in sorted({key[0] for key in runs}):
        window_runs = [
            (key, run) for key, run in runs.items() if key[0] == window_id
        ]
        urls = [url for _, run in window_runs for url in run["urls"]]
        hostnames = [
            hostname
            for url in urls
            if (hostname := (urlsplit(url).hostname or "").lower())
        ]
        providers = []
        for provider in sorted({key[1] for key, _ in window_runs}):
            provider_run_entries = sorted(
                (
                    (key, run)
                    for key, run in window_runs
                    if key[1] == provider
                ),
                key=lambda item: item[0][2],
            )
            provider_runs = [run for _, run in provider_run_entries]
            provider_urls = [url for run in provider_runs for url in run["urls"]]
            provider_hosts = [
                hostname
                for url in provider_urls
                if (hostname := (urlsplit(url).hostname or "").lower())
            ]
            host_counts = Counter(provider_hosts)
            maximum = max(host_counts.values(), default=0)
            providers.append(
                {
                    "provider": provider,
                    "model": sorted({run["model"] for run in provider_runs}),
                    "completedRuns": len(provider_runs),
                    "citationCountsByRun": [
                        len(run["urls"]) for run in provider_runs
                    ],
                    "concreteUrlOccurrences": len(provider_urls),
                    "distinctConcreteUrls": len(set(provider_urls)),
                    "distinctHostnames": len(set(provider_hosts)),
                    "leadingHostnames": sorted(
                        host
                        for host, count in host_counts.items()
                        if count == maximum
                    ),
                    "leadingHostnameOccurrences": maximum,
                    "targetCitationRuns": sum(
                        run["targetCited"] for run in provider_runs
                    ),
                    "brandMentionRuns": sum(
                        run["brandMentioned"] for run in provider_runs
                    ),
                }
            )
        windows.append(
            {
                "windowId": window_id,
                "phase": sorted({run["phase"] for _, run in window_runs})[0],
                "completedRuns": len(window_runs),
                "verifiableRuns": sum(
                    run["citationSurfaceVerifiable"] for _, run in window_runs
                ),
                "concreteUrlOccurrences": len(urls),
                "discardedPlaceholderCount": sum(
                    run["discardedPlaceholderCount"] for _, run in window_runs
                ),
                "distinctConcreteUrls": len(set(urls)),
                "distinctHostnames": len(set(hostnames)),
                "targetCitationRuns": sum(
                    run["targetCited"] for _, run in window_runs
                ),
                "brandMentionRuns": sum(
                    run["brandMentioned"] for _, run in window_runs
                ),
                "providers": providers,
            }
        )

    expected_by_window = {row["window_id"]: row for row in expected_rows}
    if set(expected_by_window) != {window["windowId"] for window in windows}:
        raise ValueError("formal-window inventory drifted")
    field_map = {
        "completedRuns": "completed_runs",
        "verifiableRuns": "verifiable_runs",
        "concreteUrlOccurrences": "concrete_url_occurrences",
        "discardedPlaceholderCount": "discarded_placeholder_count",
        "distinctConcreteUrls": "distinct_concrete_urls",
        "distinctHostnames": "distinct_hostnames",
        "targetCitationRuns": "target_citation_runs",
        "brandMentionRuns": "brand_mention_runs",
    }
    for window in windows:
        expected = expected_by_window[window["windowId"]]
        for output_field, csv_field in field_map.items():
            if window[output_field] != int(expected[csv_field]):
                raise ValueError(
                    f"{window['windowId']} {output_field} does not match "
                    f"{SUMMARY_FILE}"
                )
        if (
            expected["counts_as_geo_success"] != "false"
            or window["targetCitationRuns"] != 0
            or window["brandMentionRuns"] != 0
        ):
            raise ValueError("zero-result GEO evidence boundary drifted")

    expected_providers = {
        (row["window_id"], row["provider"]): row
        for row in expected_provider_rows
    }
    actual_providers = {
        (window["windowId"], provider["provider"]): provider
        for window in windows
        for provider in window["providers"]
    }
    if set(expected_providers) != set(actual_providers):
        raise ValueError("provider-window inventory drifted")
    baseline_models = {
        provider["provider"]: provider["model"][0]
        for window in windows
        if window["windowId"] == "B"
        for provider in window["providers"]
    }
    provider_field_map = {
        "completedRuns": "completed_runs",
        "concreteUrlOccurrences": "concrete_url_occurrences",
        "distinctConcreteUrls": "distinct_concrete_urls",
        "distinctHostnames": "distinct_hostnames",
        "leadingHostnameOccurrences": "leading_hostname_occurrences",
        "targetCitationRuns": "target_citation_runs",
        "brandMentionRuns": "brand_mention_runs",
    }
    for key, provider in actual_providers.items():
        expected = expected_providers[key]
        for output_field, csv_field in provider_field_map.items():
            if provider[output_field] != int(expected[csv_field]):
                raise ValueError(
                    f"{key} {output_field} does not match "
                    f"{PROVIDER_SUMMARY_FILE}"
                )
        if (
            provider["model"] != [expected["model"]]
            or "|".join(
                str(value) for value in provider["citationCountsByRun"]
            )
            != expected["citation_counts_by_run"]
            or "|".join(provider["leadingHostnames"])
            != expected["leading_hostnames"]
            or csv_bool(expected["same_model_as_window_b"])
            != (baseline_models[provider["provider"]] == expected["model"])
            or expected["counts_as_source_quality_ranking"] != "false"
            or expected["counts_as_geo_success"] != "false"
            or provider["targetCitationRuns"] != 0
            or provider["brandMentionRuns"] != 0
        ):
            raise ValueError("provider-window evidence boundary drifted")

    def selected_runs(window_id: str, provider: str) -> list[dict[str, Any]]:
        return [
            run
            for (run_window, run_provider, _), run in sorted(runs.items())
            if run_window == window_id and run_provider == provider
        ]

    def url_hostname(url: str) -> str:
        return (urlsplit(url).hostname or "").lower()

    actual_host_rows: dict[tuple[str, str, str], dict[str, str]] = {}
    for window in windows:
        window_id = window["windowId"]
        for provider_summary in window["providers"]:
            provider = provider_summary["provider"]
            provider_runs = selected_runs(window_id, provider)
            model = provider_summary["model"][0]
            urls = [url for run in provider_runs for url in run["urls"]]
            host_counts = Counter(url_hostname(url) for url in urls)
            for hostname, occurrence_count in host_counts.items():
                coverage_count = sum(
                    any(url_hostname(url) == hostname for url in run["urls"])
                    for run in provider_runs
                )
                distinct_urls = {
                    url for url in urls if url_hostname(url) == hostname
                }
                key = (window_id, provider, hostname)
                actual_host_rows[key] = {
                    "window_id": window_id,
                    "phase": window["phase"],
                    "provider": provider,
                    "model": model,
                    "provider_run_count": str(len(provider_runs)),
                    "hostname": hostname,
                    "citation_occurrences": str(occurrence_count),
                    "run_coverage_count": str(coverage_count),
                    "run_coverage_rate": f"{coverage_count / len(provider_runs):.6f}",
                    "distinct_cited_urls": str(len(distinct_urls)),
                    "counts_as_source_quality_ranking": "false",
                    "counts_as_geo_success": "false",
                }
    expected_host_by_key = {
        (row["window_id"], row["provider"], row["hostname"]): row
        for row in expected_host_rows
    }
    if (
        len(expected_host_by_key) != 92
        or set(expected_host_by_key) != set(actual_host_rows)
        or any(
            expected_host_by_key[key] != actual
            for key, actual in actual_host_rows.items()
        )
    ):
        raise ValueError("citation-host frequency projection drifted")

    if len(expected_overlap_rows) != 9:
        raise ValueError("citation-host overlap inventory drifted")
    expected_overlap_keys = {
        (
            row["comparison_scope"],
            row["left_window_id"],
            row["right_window_id"],
            row["left_provider"],
            row["right_provider"],
        )
        for row in expected_overlap_rows
    }
    if len(expected_overlap_keys) != len(expected_overlap_rows):
        raise ValueError("citation-host overlap keys are not unique")
    for expected in expected_overlap_rows:
        left_runs = selected_runs(
            expected["left_window_id"], expected["left_provider"]
        )
        right_runs = selected_runs(
            expected["right_window_id"], expected["right_provider"]
        )
        if not left_runs or not right_runs:
            raise ValueError("citation-host overlap references an unknown side")
        left_models = {run["model"] for run in left_runs}
        right_models = {run["model"] for run in right_runs}
        if len(left_models) != 1 or len(right_models) != 1:
            raise ValueError("citation-host overlap requires one model per side")
        left_model = next(iter(left_models))
        right_model = next(iter(right_models))
        left_hosts = {
            url_hostname(url) for run in left_runs for url in run["urls"]
        }
        right_hosts = {
            url_hostname(url) for run in right_runs for url in run["urls"]
        }
        intersection = left_hosts & right_hosts
        union = left_hosts | right_hosts
        same_provider = expected["left_provider"] == expected["right_provider"]
        same_model = left_model == right_model
        actual = {
            "comparison_scope": expected["comparison_scope"],
            "left_window_id": expected["left_window_id"],
            "right_window_id": expected["right_window_id"],
            "left_provider": expected["left_provider"],
            "right_provider": expected["right_provider"],
            "left_model": left_model,
            "right_model": right_model,
            "left_hostname_count": str(len(left_hosts)),
            "right_hostname_count": str(len(right_hosts)),
            "intersection_hostname_count": str(len(intersection)),
            "union_hostname_count": str(len(union)),
            "jaccard_similarity": (
                f"{len(intersection) / len(union):.6f}" if union else ""
            ),
            "same_query": "true",
            "same_provider": str(same_provider).lower(),
            "same_model": str(same_model).lower(),
            "strict_same_model_trend": str(
                expected["comparison_scope"] == "cross_window_same_provider"
                and same_provider
                and same_model
            ).lower(),
            "counts_as_source_quality_ranking": "false",
            "counts_as_geo_success": "false",
        }
        if actual != expected:
            raise ValueError("citation-host overlap projection drifted")

    providers = sorted({key[1] for key in runs})
    actual_persistence_rows: dict[tuple[str, str], dict[str, str]] = {}
    for provider in providers:
        baseline_runs = selected_runs("B", provider)
        current_runs = selected_runs("C", provider)
        if not baseline_runs or not current_runs:
            raise ValueError("URL persistence requires B and C provider runs")
        baseline_models = {run["model"] for run in baseline_runs}
        current_models = {run["model"] for run in current_runs}
        if len(baseline_models) != 1 or len(current_models) != 1:
            raise ValueError("URL persistence requires one model per window")
        baseline_model = next(iter(baseline_models))
        current_model = next(iter(current_models))
        same_model = baseline_model == current_model
        urls = sorted(
            {
                url
                for run in [*baseline_runs, *current_runs]
                for url in run["urls"]
            }
        )
        for url in urls:
            baseline_coverage = sum(
                url in run["urls"] for run in baseline_runs
            )
            current_coverage = sum(url in run["urls"] for run in current_runs)
            present_in_both = baseline_coverage > 0 and current_coverage > 0
            key = (provider, url)
            actual_persistence_rows[key] = {
                "provider": provider,
                "baseline_model": baseline_model,
                "current_model": current_model,
                "same_model_across_windows": str(same_model).lower(),
                "hostname": url_hostname(url),
                "cited_url": url,
                "baseline_run_count": str(len(baseline_runs)),
                "baseline_run_coverage_count": str(baseline_coverage),
                "baseline_run_coverage_rate": (
                    f"{baseline_coverage / len(baseline_runs):.6f}"
                ),
                "current_run_count": str(len(current_runs)),
                "current_run_coverage_count": str(current_coverage),
                "current_run_coverage_rate": (
                    f"{current_coverage / len(current_runs):.6f}"
                ),
                "present_in_both_windows": str(present_in_both).lower(),
                "strict_cross_window_persistence_allowed": str(
                    same_model and present_in_both
                ).lower(),
                "counts_as_source_quality_ranking": "false",
                "counts_as_geo_success": "false",
            }
    expected_persistence_by_key = {
        (row["provider"], row["cited_url"]): row
        for row in expected_persistence_rows
    }
    if (
        len(expected_persistence_by_key) != 98
        or set(expected_persistence_by_key) != set(actual_persistence_rows)
        or any(
            expected_persistence_by_key[key] != actual
            for key, actual in actual_persistence_rows.items()
        )
    ):
        raise ValueError("citation-URL persistence projection drifted")

    current_evidence = reproduce_current_evidence(bundle_dir)
    return {
        "schemaVersion": "1.1.0",
        "status": "reproduced",
        "sourceFiles": [
            RUN_FILE,
            SUMMARY_FILE,
            PROVIDER_SUMMARY_FILE,
            HOST_FREQUENCY_FILE,
            HOST_OVERLAP_FILE,
            URL_PERSISTENCE_FILE,
            FIVE_BATCH_RUN_CSV,
            FIVE_BATCH_RUN_JSON,
            FIVE_BATCH_URL_PROFILE_JSON,
            PROVIDER_HOST_PERSISTENCE_JSON,
            BAIDU_SIX_OBSERVATION_JSON,
            CROSS_SURFACE_HOST_PERSISTENCE_JSON,
        ],
        "verifiedProjectionRows": {
            "citationHostFrequency": len(actual_host_rows),
            "citationHostOverlap": len(expected_overlap_rows),
            "citationUrlPersistence": len(actual_persistence_rows),
        },
        "windows": windows,
        "currentEvidence": current_evidence,
        "countsAsSourceQualityRanking": False,
        "countsAsGeoSuccess": False,
    }


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Reproduce the fixed-query benchmark window summaries."
    )
    parser.add_argument(
        "--bundle-dir",
        type=Path,
        default=Path(__file__).resolve().parent,
    )
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()
    result = reproduce(args.bundle_dir)
    text = json.dumps(result, ensure_ascii=False, indent=2) + "\n"
    if args.output:
        args.output.write_text(text, encoding="utf-8")
    else:
        print(text, end="")


if __name__ == "__main__":
    main()
