#!/usr/bin/env python3
"""Benchmark E1 valid-FOV preprocessing variants on one sealed frame slice."""

from __future__ import annotations

import argparse
import hashlib
import json
import os
import resource
import time
from collections import Counter
from datetime import UTC, datetime
from pathlib import Path
from typing import Any

from run_recorded_perception_epoch import (
    INSTANCE_MASK_THRESHOLD,
    INSTANCE_SCORE_THRESHOLD,
    SEMANTIC_MODEL_ID,
    SEMANTIC_REVISION,
    _canonical_json,
    _GpuTelemetry,
    _instance_overlay,
    _model_files,
    _percentiles,
    _read_object,
    _read_timeline,
    _semantic_overlay,
    _sha256,
    _valid_sha256,
    _validate_job,
    _write_json,
    _write_png,
)

QUALIFICATION_SCHEMA = "missioncore.recorded-qualification-slice/v1"
QUALIFICATION_IDENTITY_SCHEMA = "missioncore.recorded-qualification-slice-identity/v1"
VALID_FOV_SCHEMA = "missioncore.k1-valid-fov-mask/v1"
VALID_FOV_IDENTITY_SCHEMA = "missioncore.k1-valid-fov-mask-identity/v1"
REPORT_SCHEMA = "missioncore.perception-preprocessing-qualification-report/v1"
RESULT_SCHEMA = "missioncore.perception-preprocessing-qualification-result/v1"
RESULT_IDENTITY_SCHEMA = "missioncore.perception-preprocessing-qualification-identity/v1"
VARIANTS = ("baseline", "valid-fov-fill", "valid-fov-crop")
PREVIEW_FRAME_COUNT = 12


def _arguments() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument("--job", type=Path, required=True)
    parser.add_argument("--frames", type=Path, required=True)
    parser.add_argument("--timeline", type=Path, required=True)
    parser.add_argument("--qualification", type=Path, required=True)
    parser.add_argument("--valid-fov-root", type=Path, required=True)
    parser.add_argument("--output", type=Path, required=True)
    parser.add_argument("--cache", type=Path, required=True)
    parser.add_argument("--calibration-sha256", required=True)
    parser.add_argument("--calibration-slot", required=True)
    parser.add_argument("--telemetry-interval-seconds", type=float, default=1.0)
    return parser.parse_args()


def _load_qualification(path: Path, job: dict[str, Any]) -> tuple[dict[str, Any], list[int]]:
    manifest = _read_object(path.resolve(strict=True))
    identity = manifest.get("identity")
    identity_sha256 = manifest.get("identity_sha256")
    input_document = job["input"]
    if (
        manifest.get("schema_version") != QUALIFICATION_SCHEMA
        or not isinstance(identity, dict)
        or identity.get("schema_version") != QUALIFICATION_IDENTITY_SCHEMA
        or not _valid_sha256(identity_sha256)
        or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
        or manifest.get("generation_id") != f"qualification-slice-{identity_sha256}"
        or identity.get("job_id") != job["job_id"]
        or identity.get("input_sha256") != job["input_sha256"]
        or identity.get("source_id") != input_document["source_id"]
        or identity.get("codec_epoch") != input_document["codec_epoch"]
        or identity.get("source_frame_count") != input_document["segment_count"]
        or identity.get("policy") != "uniform-frame-index-full-epoch/v1"
    ):
        raise RuntimeError("qualification slice identity is invalid")
    rows = manifest.get("frames")
    selected = identity.get("selected_frames")
    if not isinstance(rows, list) or not isinstance(selected, list) or len(rows) != len(selected):
        raise RuntimeError("qualification slice frame set is invalid")
    indices: list[int] = []
    previous = -1
    for row, selected_row in zip(rows, selected, strict=True):
        if not isinstance(row, dict) or not isinstance(selected_row, dict):
            raise RuntimeError("qualification frame descriptor is invalid")
        frame_index = row.get("frame_index")
        sequence = row.get("sequence")
        digest = row.get("segment_sha256")
        if (
            not isinstance(frame_index, int)
            or isinstance(frame_index, bool)
            or not previous < frame_index < int(input_document["segment_count"])
            or sequence != frame_index + 1
            or not _valid_sha256(digest)
            or selected_row
            != {
                "frame_index": frame_index,
                "sequence": sequence,
                "segment_sha256": digest,
            }
        ):
            raise RuntimeError("qualification frame binding is invalid")
        indices.append(frame_index)
        previous = frame_index
    if not indices:
        raise RuntimeError("qualification slice is empty")
    return manifest, indices


def _load_valid_fov(
    root: Path,
    *,
    job: dict[str, Any],
    calibration_sha256: str,
    calibration_slot: str,
) -> tuple[dict[str, Any], Any, tuple[int, int, int, int]]:
    import numpy as np
    from PIL import Image

    resolved = root.resolve(strict=True)
    manifest = _read_object(resolved / "manifest.json")
    identity = manifest.get("identity")
    identity_sha256 = manifest.get("identity_sha256")
    artifact = manifest.get("artifact")
    geometry = manifest.get("geometry")
    if (
        manifest.get("schema_version") != VALID_FOV_SCHEMA
        or not isinstance(identity, dict)
        or identity.get("schema_version") != VALID_FOV_IDENTITY_SCHEMA
        or not _valid_sha256(identity_sha256)
        or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
        or manifest.get("generation_id") != f"valid-fov-mask-{identity_sha256}"
        or identity.get("calibration_sha256") != calibration_sha256
        or identity.get("calibration_slot") != calibration_slot
        or identity.get("source_id") != job["input"]["source_id"]
        or identity.get("admitted_resolution") != [800, 600]
        or not isinstance(artifact, dict)
        or artifact.get("path") != "mask.png"
        or artifact.get("media_type") != "image/png"
        or not _valid_sha256(artifact.get("sha256"))
        or not isinstance(geometry, dict)
    ):
        raise RuntimeError("valid-FOV identity is invalid")
    mask_path = (resolved / "mask.png").resolve(strict=True)
    if mask_path.parent != resolved or _sha256(mask_path) != artifact["sha256"]:
        raise RuntimeError("valid-FOV mask artifact changed")
    with Image.open(mask_path) as opened:
        if opened.mode != "L" or opened.size != (800, 600):
            raise RuntimeError("valid-FOV mask format changed")
        mask = np.asarray(opened, dtype=np.uint8)
    if not np.isin(mask, (0, 255)).all():
        raise RuntimeError("valid-FOV mask is not binary")
    crop_value = geometry.get("crop_xyxy_exclusive")
    if (
        not isinstance(crop_value, list)
        or len(crop_value) != 4
        or not all(isinstance(value, int) and not isinstance(value, bool) for value in crop_value)
    ):
        raise RuntimeError("valid-FOV crop is invalid")
    crop = tuple(int(value) for value in crop_value)
    left, top, right, bottom = crop
    if not 0 <= left < right <= 800 or not 0 <= top < bottom <= 600:
        raise RuntimeError("valid-FOV crop escapes the image")
    if int(np.count_nonzero(mask)) != geometry.get("valid_pixel_count"):
        raise RuntimeError("valid-FOV pixel count changed")
    return manifest, mask > 0, crop


def _variant_image(
    image: Any,
    valid_mask: Any,
    crop: tuple[int, int, int, int],
    variant: str,
) -> Any:
    import numpy as np

    if variant == "baseline":
        return image
    masked = np.where(valid_mask[..., None], image, 0).astype(np.uint8, copy=False)
    if variant == "valid-fov-fill":
        return masked
    if variant == "valid-fov-crop":
        left, top, right, bottom = crop
        return masked[top:bottom, left:right]
    raise RuntimeError(f"unknown preprocessing variant: {variant}")


def _full_mask(
    local_mask: Any,
    *,
    variant: str,
    valid_mask: Any,
    crop: tuple[int, int, int, int],
) -> Any:
    import numpy as np

    if variant != "valid-fov-crop":
        result = np.asarray(local_mask, dtype=bool)
    else:
        result = np.zeros(valid_mask.shape, dtype=bool)
        left, top, right, bottom = crop
        if local_mask.shape != (bottom - top, right - left):
            raise RuntimeError("cropped instance mask shape changed")
        result[top:bottom, left:right] = local_mask
    if variant != "baseline":
        result = np.logical_and(result, valid_mask)
    return result


def _full_box(
    box_xyxy: list[float],
    *,
    variant: str,
    crop: tuple[int, int, int, int],
) -> list[float]:
    if variant == "valid-fov-crop":
        left, top, _right, _bottom = crop
        return [
            box_xyxy[0] + left,
            box_xyxy[1] + top,
            box_xyxy[2] + left,
            box_xyxy[3] + top,
        ]
    return box_xyxy


def _full_semantic(
    local: Any,
    *,
    variant: str,
    valid_mask: Any,
    crop: tuple[int, int, int, int],
) -> Any:
    import numpy as np

    if variant != "valid-fov-crop":
        result = np.asarray(local, dtype=np.uint8)
    else:
        result = np.full(valid_mask.shape, 255, dtype=np.uint8)
        left, top, right, bottom = crop
        if local.shape != (bottom - top, right - left):
            raise RuntimeError("cropped semantic mask shape changed")
        result[top:bottom, left:right] = local
    if variant != "baseline":
        result = result.copy()
        result[~valid_mask] = 255
    return result


def _resource_snapshot() -> dict[str, float]:
    usage = resource.getrusage(resource.RUSAGE_SELF)
    result = {
        "user_cpu_seconds": float(usage.ru_utime),
        "system_cpu_seconds": float(usage.ru_stime),
        "minor_page_faults": float(usage.ru_minflt),
        "major_page_faults": float(usage.ru_majflt),
        "voluntary_context_switches": float(usage.ru_nvcsw),
        "involuntary_context_switches": float(usage.ru_nivcsw),
    }
    try:
        for line in Path("/proc/self/io").read_text(encoding="ascii").splitlines():
            name, value = line.split(":", 1)
            if name in {"read_bytes", "write_bytes", "rchar", "wchar"}:
                result[f"proc_io_{name}"] = float(value.strip())
    except (OSError, UnicodeDecodeError, ValueError):
        pass
    return result


def _resource_delta(before: dict[str, float], after: dict[str, float]) -> dict[str, float]:
    return {
        name: round(value - before.get(name, value), 6)
        for name, value in after.items()
        if name in before
    }


def _metric_state() -> dict[str, Any]:
    return {
        "instance_source_decode_ms": [],
        "instance_preprocess_ms": [],
        "instance_host_to_device_ms": [],
        "instance_forward_ms": [],
        "instance_postprocess_ms": [],
        "semantic_source_decode_ms": [],
        "semantic_preprocess_ms": [],
        "semantic_host_to_device_ms": [],
        "semantic_forward_ms": [],
        "semantic_postprocess_ms": [],
        "instances": 0,
        "instance_scores": [],
        "instance_labels": Counter(),
        "huge_masks_over_half_valid_fov": 0,
        "huge_boxes_over_half_full_frame": 0,
        "predicted_mask_pixels": 0,
        "predicted_mask_pixels_outside_valid_fov": 0,
        "frames_with_outside_valid_fov_instance_pixels": 0,
        "semantic_labels": Counter(),
        "semantic_disagreement_with_baseline": [],
    }


def _latency_document(state: dict[str, Any]) -> dict[str, Any]:
    return {
        branch: {
            name: _percentiles(
                [float(value) for value in state[f"{branch}_{name}"]]
            )
            for name in (
                "source_decode_ms",
                "preprocess_ms",
                "host_to_device_ms",
                "forward_ms",
                "postprocess_ms",
            )
        }
        for branch in ("instance", "semantic")
    }


def _metric_document(state: dict[str, Any], frame_count: int) -> dict[str, Any]:
    scores = [float(value) for value in state["instance_scores"]]
    outside = int(state["predicted_mask_pixels_outside_valid_fov"])
    total = int(state["predicted_mask_pixels"])
    disagreements = [float(value) for value in state["semantic_disagreement_with_baseline"]]
    return {
        "frames": frame_count,
        "latency_ms": _latency_document(state),
        "instances": int(state["instances"]),
        "instances_per_frame": round(int(state["instances"]) / frame_count, 6),
        "instance_score": _percentiles(scores),
        "instance_labels": dict(state["instance_labels"].most_common()),
        "huge_masks_over_half_valid_fov": int(state["huge_masks_over_half_valid_fov"]),
        "huge_boxes_over_half_full_frame": int(state["huge_boxes_over_half_full_frame"]),
        "predicted_mask_pixels": total,
        "predicted_mask_pixels_outside_valid_fov": outside,
        "predicted_mask_outside_fraction": round(outside / total, 9) if total else 0.0,
        "frames_with_outside_valid_fov_instance_pixels": int(
            state["frames_with_outside_valid_fov_instance_pixels"]
        ),
        "semantic_labels_inside_valid_fov": dict(state["semantic_labels"].most_common()),
        "semantic_disagreement_with_baseline_inside_valid_fov": _percentiles(disagreements),
    }


def _preview_indices(indices: list[int]) -> set[int]:
    admitted = min(PREVIEW_FRAME_COUNT, len(indices))
    if admitted == 1:
        return {indices[len(indices) // 2]}
    positions = {
        (position * (len(indices) - 1) + (admitted - 1) // 2) // (admitted - 1)
        for position in range(admitted)
    }
    return {indices[position] for position in positions}


def _run(args: argparse.Namespace) -> int:
    if not _valid_sha256(args.calibration_sha256):
        raise RuntimeError("calibration SHA-256 is invalid")
    job_root = args.job.resolve(strict=True)
    frames_root = args.frames.resolve(strict=True)
    timeline_path = args.timeline.resolve(strict=True)
    output_root = args.output.resolve()
    cache_root = args.cache.resolve(strict=True)
    if output_root.exists() or not frames_root.is_dir():
        raise RuntimeError("output must be absent and frames must be a directory")
    job = _validate_job(job_root)
    input_document = job["input"]
    frame_count = int(input_document["segment_count"])
    timeline = input_document["timeline"]
    timestamps = _read_timeline(
        timeline_path,
        frame_count,
        float(timeline["start_seconds"]),
        float(timeline["end_seconds"]),
    )
    qualification, selected_indices = _load_qualification(args.qualification, job)
    valid_fov, valid_mask, crop = _load_valid_fov(
        args.valid_fov_root,
        job=job,
        calibration_sha256=args.calibration_sha256,
        calibration_slot=args.calibration_slot,
    )
    frame_paths = [frames_root / f"frame-{index + 1:06d}.png" for index in selected_indices]
    if not all(path.is_file() for path in frame_paths):
        raise RuntimeError("qualification decoded frame set is incomplete")

    import numpy as np
    import torch
    import torch.nn.functional as functional
    import torchvision
    import transformers
    from huggingface_hub import snapshot_download
    from PIL import Image
    from torchvision.models.detection import (
        MaskRCNN_ResNet50_FPN_V2_Weights,
        maskrcnn_resnet50_fpn_v2,
    )
    from transformers import AutoImageProcessor, BeitForSemanticSegmentation

    if not torch.cuda.is_available():
        raise RuntimeError("CUDA is required for preprocessing qualification")
    device = torch.device("cuda:0")
    output_root.mkdir(mode=0o700, parents=True, exist_ok=False)
    previews_root = output_root / "previews"
    previews_root.mkdir(mode=0o700)
    for variant in VARIANTS:
        (previews_root / variant).mkdir(mode=0o700)
    telemetry_path = output_root / "gpu-telemetry.jsonl"
    metrics = {variant: _metric_state() for variant in VARIANTS}
    preview_frame_indices = _preview_indices(selected_indices)
    preview_instances: dict[tuple[str, int], tuple[Any, list[dict[str, Any]]]] = {}
    valid_pixel_count = int(np.count_nonzero(valid_mask))
    total_pixel_count = int(valid_mask.size)
    resource_before = _resource_snapshot()
    wall_started = time.perf_counter()

    with telemetry_path.open("x", encoding="utf-8", newline="\n") as telemetry_stream:
        with _GpuTelemetry(telemetry_stream, args.telemetry_interval_seconds) as telemetry:
            instance_weights = MaskRCNN_ResNet50_FPN_V2_Weights.DEFAULT
            instance_model = maskrcnn_resnet50_fpn_v2(weights=instance_weights).to(device).eval()
            instance_labels = list(instance_weights.meta["categories"])
            with Image.open(frame_paths[0]) as opened:
                warm_image = opened.convert("RGB")
            with torch.inference_mode():
                warm_tensor = instance_weights.transforms()(warm_image).to(device)
                _ = instance_model([warm_tensor])[0]
                torch.cuda.synchronize()
            del warm_tensor
            torch.cuda.reset_peak_memory_stats()

            with torch.inference_mode():
                for order, (frame_index, path) in enumerate(
                    zip(selected_indices, frame_paths, strict=True),
                    start=1,
                ):
                    decode_started = time.perf_counter()
                    with Image.open(path) as opened:
                        image = np.asarray(opened.convert("RGB"), dtype=np.uint8)
                    decode_ms = (time.perf_counter() - decode_started) * 1000.0
                    for variant in VARIANTS:
                        state = metrics[variant]
                        state["instance_source_decode_ms"].append(decode_ms)
                        preprocess_started = time.perf_counter()
                        variant_image = _variant_image(image, valid_mask, crop, variant)
                        tensor = instance_weights.transforms()(Image.fromarray(variant_image))
                        state["instance_preprocess_ms"].append(
                            (time.perf_counter() - preprocess_started) * 1000.0
                        )
                        torch.cuda.synchronize()
                        transfer_started = time.perf_counter()
                        tensor = tensor.to(device)
                        torch.cuda.synchronize()
                        state["instance_host_to_device_ms"].append(
                            (time.perf_counter() - transfer_started) * 1000.0
                        )
                        torch.cuda.synchronize()
                        forward_started = time.perf_counter()
                        prediction = instance_model([tensor])[0]
                        torch.cuda.synchronize()
                        state["instance_forward_ms"].append(
                            (time.perf_counter() - forward_started) * 1000.0
                        )
                        post_started = time.perf_counter()
                        scores = prediction["scores"].detach().cpu().numpy()
                        keep = np.flatnonzero(scores >= INSTANCE_SCORE_THRESHOLD)
                        index_map = np.zeros(valid_mask.shape, dtype=np.uint16)
                        instances: list[dict[str, Any]] = []
                        frame_outside = 0
                        for output_index in keep:
                            local_mask = (
                                prediction["masks"][output_index, 0].detach().cpu().numpy()
                                >= INSTANCE_MASK_THRESHOLD
                            )
                            full_mask = _full_mask(
                                local_mask,
                                variant=variant,
                                valid_mask=valid_mask,
                                crop=crop,
                            )
                            mask_pixels = int(np.count_nonzero(full_mask))
                            if mask_pixels < 8:
                                continue
                            original_full_mask = _full_mask(
                                local_mask,
                                variant="baseline" if variant != "valid-fov-crop" else variant,
                                valid_mask=np.ones_like(valid_mask),
                                crop=crop,
                            )
                            outside_pixels = int(
                                np.count_nonzero(np.logical_and(original_full_mask, ~valid_mask))
                            )
                            frame_outside += outside_pixels
                            label_id = int(prediction["labels"][output_index].item())
                            score = float(scores[output_index])
                            box_values = (
                                prediction["boxes"][output_index].detach().cpu().tolist()
                            )
                            box = _full_box(
                                [float(value) for value in box_values],
                                variant=variant,
                                crop=crop,
                            )
                            instance_id = len(instances) + 1
                            index_map[np.logical_and(full_mask, index_map == 0)] = instance_id
                            instances.append(
                                {
                                    "instance_id": instance_id,
                                    "class_id": label_id,
                                    "label": instance_labels[label_id],
                                    "score": round(score, 9),
                                    "box_xyxy": [round(value, 6) for value in box],
                                    "mask_pixels": mask_pixels,
                                    "outside_valid_fov_pixels": outside_pixels,
                                }
                            )
                            state["instances"] += 1
                            state["instance_scores"].append(score)
                            state["instance_labels"][instance_labels[label_id]] += 1
                            state["predicted_mask_pixels"] += int(
                                np.count_nonzero(original_full_mask)
                            )
                            state["predicted_mask_pixels_outside_valid_fov"] += outside_pixels
                            if mask_pixels / valid_pixel_count > 0.5:
                                state["huge_masks_over_half_valid_fov"] += 1
                            box_area = max(0.0, box[2] - box[0]) * max(0.0, box[3] - box[1])
                            if box_area / total_pixel_count > 0.5:
                                state["huge_boxes_over_half_full_frame"] += 1
                        if frame_outside:
                            state["frames_with_outside_valid_fov_instance_pixels"] += 1
                        if frame_index in preview_frame_indices:
                            preview_instances[(variant, frame_index)] = (index_map, instances)
                        state["instance_postprocess_ms"].append(
                            (time.perf_counter() - post_started) * 1000.0
                        )
                        del tensor, prediction
                    if order % 32 == 0 or order == len(selected_indices):
                        print(
                            json.dumps(
                                {
                                    "phase": "instance",
                                    "qualification_frames_processed": order,
                                    "qualification_frames_total": len(selected_indices),
                                },
                                sort_keys=True,
                            ),
                            flush=True,
                        )

            checkpoint = Path(instance_weights.url).name
            checkpoint_path = Path(torch.hub.get_dir()) / "checkpoints" / checkpoint
            del instance_model
            torch.cuda.empty_cache()

            semantic_snapshot = Path(
                snapshot_download(
                    repo_id=SEMANTIC_MODEL_ID,
                    revision=SEMANTIC_REVISION,
                    cache_dir=cache_root / "huggingface",
                    allow_patterns=(
                        "config.json",
                        "preprocessor_config.json",
                        "pytorch_model.bin",
                    ),
                )
            )
            processor = AutoImageProcessor.from_pretrained(
                semantic_snapshot,
                local_files_only=True,
                use_fast=False,
            )
            semantic_model, loading = BeitForSemanticSegmentation.from_pretrained(
                semantic_snapshot,
                local_files_only=True,
                output_loading_info=True,
            )
            load_problems = {
                name: loading.get(name, [])
                for name in ("missing_keys", "unexpected_keys", "mismatched_keys", "error_msgs")
                if loading.get(name)
            }
            if load_problems:
                raise RuntimeError(
                    "semantic checkpoint did not load exactly: " + json.dumps(load_problems)
                )
            semantic_model = semantic_model.to(device).eval()
            semantic_labels = {
                int(key): str(value) for key, value in semantic_model.config.id2label.items()
            }
            with Image.open(frame_paths[0]) as opened:
                warm_image = opened.convert("RGB")
            warm_inputs = processor(images=warm_image, return_tensors="pt")
            warm_inputs = {name: value.to(device) for name, value in warm_inputs.items()}
            with torch.inference_mode():
                _ = semantic_model(**warm_inputs).logits
                torch.cuda.synchronize()
            del warm_inputs

            preview_sequence = {
                frame_index: sequence
                for sequence, frame_index in enumerate(sorted(preview_frame_indices), start=1)
            }
            with torch.inference_mode():
                for order, (frame_index, path) in enumerate(
                    zip(selected_indices, frame_paths, strict=True),
                    start=1,
                ):
                    decode_started = time.perf_counter()
                    with Image.open(path) as opened:
                        image = np.asarray(opened.convert("RGB"), dtype=np.uint8)
                    decode_ms = (time.perf_counter() - decode_started) * 1000.0
                    semantic_by_variant: dict[str, Any] = {}
                    for variant in VARIANTS:
                        state = metrics[variant]
                        state["semantic_source_decode_ms"].append(decode_ms)
                        preprocess_started = time.perf_counter()
                        variant_image = _variant_image(image, valid_mask, crop, variant)
                        inputs = processor(
                            images=Image.fromarray(variant_image),
                            return_tensors="pt",
                        )
                        state["semantic_preprocess_ms"].append(
                            (time.perf_counter() - preprocess_started) * 1000.0
                        )
                        torch.cuda.synchronize()
                        transfer_started = time.perf_counter()
                        inputs = {name: value.to(device) for name, value in inputs.items()}
                        torch.cuda.synchronize()
                        state["semantic_host_to_device_ms"].append(
                            (time.perf_counter() - transfer_started) * 1000.0
                        )
                        torch.cuda.synchronize()
                        forward_started = time.perf_counter()
                        logits = semantic_model(**inputs).logits
                        resized = functional.interpolate(
                            logits,
                            size=variant_image.shape[:2],
                            mode="bilinear",
                            align_corners=False,
                        )
                        local_semantic = (
                            resized.argmax(dim=1)[0].detach().cpu().numpy().astype(np.uint8)
                        )
                        torch.cuda.synchronize()
                        state["semantic_forward_ms"].append(
                            (time.perf_counter() - forward_started) * 1000.0
                        )
                        post_started = time.perf_counter()
                        semantic = _full_semantic(
                            local_semantic,
                            variant=variant,
                            valid_mask=valid_mask,
                            crop=crop,
                        )
                        semantic_by_variant[variant] = semantic
                        labels, counts = np.unique(semantic[valid_mask], return_counts=True)
                        for label_id, count in zip(labels, counts, strict=True):
                            state["semantic_labels"][
                                semantic_labels.get(int(label_id), f"class-{int(label_id)}")
                            ] += int(count)
                        if frame_index in preview_frame_indices:
                            display_image = _variant_image(image, valid_mask, crop, variant)
                            if variant == "valid-fov-crop":
                                full_display = np.zeros_like(image)
                                left, top, right, bottom = crop
                                full_display[top:bottom, left:right] = display_image
                                display_image = full_display
                            display_semantic = semantic.copy()
                            display_semantic[display_semantic == 255] = 0
                            semantic_overlay, _classes = _semantic_overlay(
                                display_image,
                                display_semantic,
                                semantic_labels,
                            )
                            instance_map, instances = preview_instances[(variant, frame_index)]
                            overlay = _instance_overlay(
                                semantic_overlay,
                                instance_map,
                                instances,
                            )
                            sequence = preview_sequence[frame_index]
                            _write_png(
                                previews_root / variant / f"frame-{sequence:03d}.png",
                                overlay,
                            )
                        state["semantic_postprocess_ms"].append(
                            (time.perf_counter() - post_started) * 1000.0
                        )
                        del inputs, logits, resized
                    baseline_semantic = semantic_by_variant["baseline"]
                    for variant in VARIANTS:
                        selected_semantic = semantic_by_variant[variant][valid_mask]
                        disagreement = float(
                            np.mean(selected_semantic != baseline_semantic[valid_mask])
                        )
                        metrics[variant]["semantic_disagreement_with_baseline"].append(
                            disagreement
                        )
                    if order % 32 == 0 or order == len(selected_indices):
                        print(
                            json.dumps(
                                {
                                    "phase": "semantic",
                                    "qualification_frames_processed": order,
                                    "qualification_frames_total": len(selected_indices),
                                },
                                sort_keys=True,
                            ),
                            flush=True,
                        )
            del semantic_model
            torch.cuda.empty_cache()

        wall_seconds = time.perf_counter() - wall_started
        resource_after = _resource_snapshot()
        model_files = _model_files(semantic_snapshot, checkpoint_path)
        metric_documents = {
            variant: _metric_document(metrics[variant], len(selected_indices))
            for variant in VARIANTS
        }
        identity = {
            "schema_version": RESULT_IDENTITY_SCHEMA,
            "job_id": job["job_id"],
            "input_sha256": job["input_sha256"],
            "qualification_generation_id": qualification["generation_id"],
            "qualification_identity_sha256": qualification["identity_sha256"],
            "valid_fov_generation_id": valid_fov["generation_id"],
            "valid_fov_identity_sha256": valid_fov["identity_sha256"],
            "calibration_sha256": args.calibration_sha256,
            "calibration_slot": args.calibration_slot,
            "configuration": {
                "pipeline": "recorded-preprocessing-ab-mask-crop/v1",
                "variants": list(VARIANTS),
                "precision": "fp32",
                "batch_size": 1,
                "execution": "same-model-load-interleaved-variants-per-frame",
                "instance_score_threshold": INSTANCE_SCORE_THRESHOLD,
                "instance_mask_threshold": INSTANCE_MASK_THRESHOLD,
                "runner_sha256": _sha256(Path(__file__).resolve(strict=True)),
                "preview_frame_count": len(preview_frame_indices),
            },
            "models": {
                "instance": {
                    "id": "torchvision/maskrcnn_resnet50_fpn_v2",
                    "weights": str(instance_weights),
                },
                "semantic": {
                    "id": SEMANTIC_MODEL_ID,
                    "revision": SEMANTIC_REVISION,
                    "checkpoint_load": "exact-no-missing-unexpected-or-mismatched-keys",
                },
                "files": model_files,
            },
        }
        identity_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
        result_id = f"qualification-result-{identity_sha256}"
        report = {
            "schema_version": REPORT_SCHEMA,
            "result_id": result_id,
            "created_at_utc": datetime.now(UTC)
            .isoformat(timespec="milliseconds")
            .replace("+00:00", "Z"),
            "state": "completed",
            "identity": identity,
            "input": {
                "job_id": job["job_id"],
                "input_sha256": job["input_sha256"],
                "session_id": input_document["session_id"],
                "source_id": input_document["source_id"],
                "codec_epoch": input_document["codec_epoch"],
                "source_frame_count": frame_count,
                "qualification_frame_count": len(selected_indices),
                "selected_frame_indices": selected_indices,
                "selected_session_seconds": [timestamps[index] for index in selected_indices],
            },
            "valid_fov": {
                "generation_id": valid_fov["generation_id"],
                "calibration_sha256": args.calibration_sha256,
                "calibration_slot": args.calibration_slot,
                "geometry": valid_fov["geometry"],
            },
            "metrics": metric_documents,
            "runtime": {
                "wall_seconds": round(wall_seconds, 6),
                "variant_model_evaluations": len(selected_indices) * len(VARIANTS) * 2,
                "gpu": torch.cuda.get_device_name(),
                "torch": torch.__version__,
                "torchvision": torchvision.__version__,
                "transformers": transformers.__version__,
                "cuda_runtime": torch.version.cuda,
                "cuda_peak_memory_allocated_mib": round(
                    torch.cuda.max_memory_allocated() / 2**20,
                    3,
                ),
                "cuda_peak_memory_reserved_mib": round(
                    torch.cuda.max_memory_reserved() / 2**20,
                    3,
                ),
                "process_peak_rss_mib": round(
                    resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
                    3,
                ),
                "resource_delta": _resource_delta(resource_before, resource_after),
                "system_load_average": [round(value, 6) for value in os.getloadavg()],
                "gpu_telemetry": telemetry.summary(),
            },
            "quality_status": {
                "ground_truth": "absent",
                "decision_scope": "preprocessing proxy comparison only",
                "not_accepted": [
                    "2D mIoU/AP",
                    "3D geometry",
                    "distance accuracy",
                    "tracking",
                    "safety",
                ],
            },
        }
        _write_json(output_root / "run-report.json", report)
        preview_artifacts = []
        for path in sorted(previews_root.glob("*/*.png")):
            preview_artifacts.append(
                {
                    "path": path.relative_to(output_root).as_posix(),
                    "byte_length": path.stat().st_size,
                    "sha256": _sha256(path),
                }
            )
        result = {
            "schema_version": RESULT_SCHEMA,
            "result_id": result_id,
            "identity_sha256": identity_sha256,
            "identity": identity,
            "artifacts": {
                "run_report": {
                    "path": "run-report.json",
                    "byte_length": (output_root / "run-report.json").stat().st_size,
                    "sha256": _sha256(output_root / "run-report.json"),
                },
                "gpu_telemetry": {
                    "path": "gpu-telemetry.jsonl",
                    "byte_length": telemetry_path.stat().st_size,
                    "sha256": _sha256(telemetry_path),
                },
                "previews": preview_artifacts,
            },
        }
        _write_json(output_root / "result.json", result)
    print(
        json.dumps(
            {
                "state": "completed",
                "result_id": result_id,
                "qualification_frames": len(selected_indices),
                "wall_seconds": round(wall_seconds, 6),
            },
            sort_keys=True,
        ),
        flush=True,
    )
    return 0


def main() -> int:
    return _run(_arguments())


if __name__ == "__main__":
    raise SystemExit(main())
