"""Read-only research: synthetic decoder counterexamples and anonymous report census.

Run with the repository's pinned Python environment. Does not connect to devices,
launch apps, alter product code, or change existing Session files. Synthetic tick
values use numer=denom=1 and are deliberately not realistic launch durations.
"""
from __future__ import annotations

import hashlib
import json
from pathlib import Path
import struct
import subprocess
import sys
from collections import Counter

ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / "MacApp/Sidecar/tests"))
from test_perfowl_launch_trace import (  # noqa: E402
    RealtimeLaunchTraceDecoder, complete_records, kd,
    INITIAL_FRAME_END_DEBUG_ID, payload, raw_v2,
)


def digest(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def synthetic_cases() -> list[dict]:
    rows = complete_records()
    def remove(ticks):
        return [row for row in rows if struct.unpack("<Q", row[:8])[0] not in ticks]
    cases = [
        ("clean-control", rows),
        ("start-present-first-phase-end-absent", remove({120})),
        ("first-frame-end-absent-later-frame-end-present",
         remove({250}) + [kd(400, INITIAL_FRAME_END_DEBUG_ID)]),
        ("frame-opener-and-first-end-absent-one-later-end-present",
         remove({240, 250}) + [kd(400, INITIAL_FRAME_END_DEBUG_ID)]),
    ]
    result = []
    for name, records in cases:
        decoder = RealtimeLaunchTraceDecoder(42)  # synthetic identity only
        decoder.consume(payload(raw_v2(*records)))
        report = decoder.report()
        result.append({
            "case": name,
            "source": "synthetic-E2-not-device",
            "fixtureOriginalTotalTicks": 140,
            "numer": 1, "denom": 1,
            **{key: report.get(key) for key in (
                "totalDurationMs", "totalQuality", "totalRepairReason",
                "launchStartTimestampNs", "traceEndTimestampNs", "requiredMissingPhases",
            )},
        })
    return result


def report_census() -> dict:
    base = Path.home() / "Library/Application Support/Perfowl/Sessions"
    paths = sorted(base.glob("*/collector-core/launch-trace-report.json"),
                   key=lambda p: (p.stat().st_mtime_ns, str(p)))
    rows, errors = [], 0
    for index, path in enumerate(paths, 1):
        try:
            report = json.loads(path.read_text())
            manifest_path = path.parent / "manifest.json"
            manifest = json.loads(manifest_path.read_text())
        except (OSError, ValueError):
            errors += 1
            continue
        counts = manifest.get("eventTypeCounts", {})
        rows.append({
            "alias": f"S{index:02}",
            "reportFileSHA256": digest(path),
            "manifestFileSHA256": digest(manifest_path),
            "algorithmVersion": report.get("algorithmVersion"),
            "totalQuality": report.get("totalQuality"),
            "totalRepairReason": report.get("totalRepairReason"),
            "numericTotal": isinstance(report.get("totalDurationMs"), (int, float)),
            "startPresent": report.get("launchStartTimestampNs") is not None,
            "terminalPresent": report.get("traceEndTimestampNs") is not None,
            "requiredMissingPhases": report.get("requiredMissingPhases"),
            "deviceLostEventMarkerCount": report.get("sourceQuality", {}).get("deviceLostEventMarkerCount"),
            "hostLiveQueueDropCount": report.get("sourceQuality", {}).get("liveQueueDropCount"),
            "completionWaitReason": manifest.get("startupCoreProfileCompletionWaitReason"),
            "captureMode": manifest.get("coreProfileCaptureMode"),
            "activityTraceListed": "pmd3.activity-trace.frame-lifetime.raw" in manifest.get("adapterIDs", []),
            "displayRawCount": counts.get("display.frame-lifetime.raw"),
            "rawRetained": manifest.get("coreProfileRawRetained"),
        })
    return {
        "scope": "existing local reports, convenience sample; not new E4; no raw replay or raw-hash validation",
        "excluded": "Sessions without a launch report are outside this census, not successful launches",
        "reportCount": len(paths), "readErrorCount": errors,
        "qualityCounts": dict(Counter(row["totalQuality"] for row in rows)),
        "rows": rows,
    }


if __name__ == "__main__":
    tracked = [
        "MacApp/Sidecar/perfowl_collector_core/launch_trace.py",
        "MacApp/Sidecar/perfowl_collector_core/realtime.py",
        "MacApp/Sidecar/perfowl_collector_core/display_performance.py",
        "MacApp/Sidecar/perfowl_collector_core/pins.py",
        "MacApp/Sidecar/perfowl_collector_core/startup_trace_codes.json",
    ]
    document = {
        "schema": "perfowl.startup-stability-reassessment/1",
        "date": "2026-09-20",
        "head": subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, text=True).strip(),
        "sourceState": "current working tree; includes pre-existing uncommitted runtime changes",
        "files": [{"path": p, "sha256": digest(ROOT / p), "differsFromHead": bool(
            subprocess.check_output(["git", "diff", "HEAD", "--", p], cwd=ROOT)
        )} for p in tracked],
        "synthetic": synthetic_cases(),
        "persistedReportCensus": report_census(),
    }
    print(json.dumps(document, ensure_ascii=False, indent=2))
