#!/usr/bin/env python3
"""Run and seal LAB E5 YOLOX-S plus ByteTrack-style temporal qualification."""

from __future__ import annotations

import argparse
import hashlib
import importlib.metadata
import json
import math
import os
import platform
import resource
import shutil
import time
import urllib.request
from collections import Counter
from dataclasses import dataclass, field
from datetime import UTC, datetime
from pathlib import Path
from typing import Any

import numpy as np
from run_e3_rectified_segmentation import _resource_delta, _resource_snapshot
from run_recorded_perception_epoch import (
    _artifact,
    _canonical_json,
    _GpuTelemetry,
    _palette,
    _percentiles,
    _sha256,
    _valid_sha256,
    _validate_job,
    _write_json,
)

PROFILE_SCHEMA = "missioncore.e5-tracking-profile/v1"
VALID_FOV_SCHEMA = "missioncore.k1-valid-fov-mask/v1"
FRAME_SCHEMA = "missioncore.e5-tracking-frame/v1"
REPORT_SCHEMA = "missioncore.e5-tracking-report/v1"
RESULT_SCHEMA = "missioncore.e5-tracking-result/v1"
IDENTITY_SCHEMA = "missioncore.e5-tracking-identity/v1"
PIPELINE_ID = "recorded-yolox-bytetrack-style-qualification/v1"

COCO_CLASSES = (
    "person",
    "bicycle",
    "car",
    "motorcycle",
    "airplane",
    "bus",
    "train",
    "truck",
    "boat",
    "traffic light",
    "fire hydrant",
    "stop sign",
    "parking meter",
    "bench",
    "bird",
    "cat",
    "dog",
    "horse",
    "sheep",
    "cow",
    "elephant",
    "bear",
    "zebra",
    "giraffe",
    "backpack",
    "umbrella",
    "handbag",
    "tie",
    "suitcase",
    "frisbee",
    "skis",
    "snowboard",
    "sports ball",
    "kite",
    "baseball bat",
    "baseball glove",
    "skateboard",
    "surfboard",
    "tennis racket",
    "bottle",
    "wine glass",
    "cup",
    "fork",
    "knife",
    "spoon",
    "bowl",
    "banana",
    "apple",
    "sandwich",
    "orange",
    "broccoli",
    "carrot",
    "hot dog",
    "pizza",
    "donut",
    "cake",
    "chair",
    "couch",
    "potted plant",
    "bed",
    "dining table",
    "toilet",
    "tv",
    "laptop",
    "mouse",
    "remote",
    "keyboard",
    "cell phone",
    "microwave",
    "oven",
    "toaster",
    "sink",
    "refrigerator",
    "book",
    "clock",
    "vase",
    "scissors",
    "teddy bear",
    "hair drier",
    "toothbrush",
)


def _arguments() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    commands = parser.add_subparsers(dest="command", required=True)

    preflight = commands.add_parser("preflight")
    preflight.add_argument("--job", type=Path, required=True)
    preflight.add_argument("--profile", type=Path, required=True)
    preflight.add_argument("--valid-fov-root", type=Path, required=True)
    preflight.add_argument("--model-root", type=Path, required=True)

    run = commands.add_parser("run")
    run.add_argument("--job", type=Path, required=True)
    run.add_argument("--profile", type=Path, required=True)
    run.add_argument("--valid-fov-root", type=Path, required=True)
    run.add_argument("--model-root", type=Path, required=True)
    run.add_argument("--frames", type=Path, required=True)
    run.add_argument("--timeline", type=Path, required=True)
    run.add_argument("--output", type=Path, required=True)
    run.add_argument("--triton-url", required=True)
    run.add_argument("--free-bytes-floor", type=int, default=0)
    run.add_argument("--orchestrator-sha256", required=True)
    run.add_argument("--container-image", required=True)
    run.add_argument("--telemetry-interval-seconds", type=float, default=1.0)

    finalize = commands.add_parser("finalize")
    finalize.add_argument("--output", type=Path, required=True)
    finalize.add_argument("--video", type=Path, required=True)
    finalize.add_argument("--contact-sheet", type=Path, required=True)
    finalize.add_argument("--extract-seconds", type=float, required=True)
    finalize.add_argument("--encode-seconds", type=float, required=True)
    finalize.add_argument("--wall-seconds", type=float, required=True)
    finalize.add_argument("--encoder", required=True)
    finalize.add_argument("--disk-free-before-bytes", type=int, required=True)
    finalize.add_argument("--disk-free-post-extract-bytes", type=int, required=True)
    finalize.add_argument("--disk-free-post-inference-bytes", type=int, required=True)
    finalize.add_argument("--disk-free-post-artifacts-bytes", type=int, required=True)
    finalize.add_argument("--disk-floor-bytes", type=int, required=True)
    finalize.add_argument("--working-set-reserve-bytes", type=int, required=True)
    return parser.parse_args()


def _read_object(path: Path) -> dict[str, Any]:
    value = json.loads(path.read_text(encoding="utf-8-sig"))
    if not isinstance(value, dict):
        raise RuntimeError(f"JSON root is not an object: {path}")
    return value


def _read_profile(path: Path) -> tuple[dict[str, Any], str]:
    resolved = path.resolve(strict=True)
    profile = _read_object(resolved)
    digest = _sha256(resolved)
    if profile.get("schema_version") != PROFILE_SCHEMA:
        raise RuntimeError("LAB E5 profile schema changed")
    detection = profile.get("detection")
    tracking = profile.get("tracking")
    if not isinstance(detection, dict) or not isinstance(tracking, dict):
        raise RuntimeError("LAB E5 profile sections are unavailable")
    probabilities = (
        detection.get("minimum_score"),
        detection.get("nms_iou_threshold"),
        detection.get("nms_containment_threshold"),
        detection.get("minimum_valid_fov_fraction"),
        detection.get("maximum_box_area_fraction"),
        tracking.get("high_score_threshold"),
        tracking.get("new_track_threshold"),
        tracking.get("primary_match_iou"),
        tracking.get("secondary_match_iou"),
    )
    if any(
        not isinstance(value, (int, float))
        or isinstance(value, bool)
        or not 0.0 < float(value) <= 1.0
        for value in probabilities
    ):
        raise RuntimeError("LAB E5 probability/overlap threshold is invalid")
    target_ids = detection.get("target_class_ids")
    if (
        not isinstance(target_ids, list)
        or not target_ids
        or len(set(target_ids)) != len(target_ids)
        or any(
            not isinstance(value, int)
            or isinstance(value, bool)
            or not 0 <= value < len(COCO_CLASSES)
            for value in target_ids
        )
    ):
        raise RuntimeError("LAB E5 target class configuration is invalid")
    if (
        tracking.get("algorithm") != "bytetrack-style-two-stage-iou/v1"
        or tracking.get("assignment_solver") != "scipy-linear-sum-assignment"
        or not isinstance(tracking.get("lost_track_buffer_frames"), int)
        or not 1 <= tracking["lost_track_buffer_frames"] <= 300
        or not isinstance(tracking.get("minimum_confirmed_hits"), int)
        or not 1 <= tracking["minimum_confirmed_hits"] <= 30
    ):
        raise RuntimeError("LAB E5 tracker configuration is invalid")
    return profile, digest


def _validate_source(job: dict[str, Any], profile: dict[str, Any]) -> None:
    source = profile["source"]
    input_document = job["input"]
    if (
        input_document.get("kind") != "canonical-camera-epoch"
        or input_document.get("source_id") != source.get("source_id")
        or source.get("resolution") != [800, 600]
    ):
        raise RuntimeError("LAB E5 profile does not match the camera job")


def _load_valid_fov(
    root: Path,
    job: dict[str, Any],
    profile: dict[str, Any],
) -> tuple[np.ndarray, dict[str, Any]]:
    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")
    source = profile["source"]
    if (
        manifest.get("schema_version") != VALID_FOV_SCHEMA
        or not isinstance(identity, dict)
        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") != source["calibration_sha256"]
        or identity.get("calibration_slot") != source["calibration_slot"]
        or identity.get("source_id") != job["input"]["source_id"]
        or identity.get("admitted_resolution") != source["resolution"]
        or not isinstance(artifact, dict)
        or artifact.get("path") != "mask.png"
        or artifact.get("mode") != "L"
        or artifact.get("inside_value") != 255
        or artifact.get("outside_value") != 0
        or not _valid_sha256(artifact.get("sha256"))
    ):
        raise RuntimeError("LAB E5 valid-FOV binding is invalid")
    mask_path = (resolved / "mask.png").resolve(strict=True)
    if (
        mask_path.parent != resolved
        or mask_path.stat().st_size != artifact.get("byte_length")
        or _sha256(mask_path) != artifact["sha256"]
    ):
        raise RuntimeError("LAB E5 valid-FOV artifact changed")
    with Image.open(mask_path) as opened:
        mask = np.asarray(opened, dtype=np.uint8)
    if mask.shape != (600, 800) or not np.isin(mask, (0, 255)).all():
        raise RuntimeError("LAB E5 valid-FOV mask pixels are invalid")
    valid = mask > 0
    return valid, {
        "generation_id": manifest["generation_id"],
        "identity_sha256": identity_sha256,
        "mask_sha256": artifact["sha256"],
        "valid_pixel_count": int(valid.sum()),
        "total_pixel_count": int(valid.size),
    }


def _verify_model(profile: dict[str, Any], model_root: Path) -> list[dict[str, Any]]:
    root = model_root.resolve(strict=True)
    model_path = (root / "1" / "model.onnx").resolve(strict=True)
    config_path = (root / "config.pbtxt").resolve(strict=True)
    if model_path.parent.parent != root or config_path.parent != root:
        raise RuntimeError("LAB E5 model path escaped its root")
    expected = profile["model"]
    files = [
        {
            "name": "model.onnx",
            "bytes": model_path.stat().st_size,
            "sha256": _sha256(model_path),
        },
        {
            "name": "config.pbtxt",
            "bytes": config_path.stat().st_size,
            "sha256": _sha256(config_path),
        },
    ]
    if (
        files[0]["sha256"] != expected["model_sha256"]
        or files[1]["sha256"] != expected["config_sha256"]
    ):
        raise RuntimeError("LAB E5 pinned model/config changed")
    return files


def _read_timeline(path: Path, expected_count: int) -> list[dict[str, Any]]:
    rows: list[dict[str, Any]] = []
    previous_source: int | None = None
    previous_time = -math.inf
    with path.resolve(strict=True).open(encoding="utf-8") as stream:
        for line in stream:
            value = json.loads(line)
            if not isinstance(value, dict):
                raise RuntimeError("LAB E5 timeline row is invalid")
            local_index = value.get("frame_index")
            source_index = value.get("source_frame_index")
            session_seconds = value.get("session_seconds")
            if (
                local_index != len(rows)
                or not isinstance(source_index, int)
                or isinstance(source_index, bool)
                or (previous_source is not None and source_index != previous_source + 1)
                or not isinstance(session_seconds, (int, float))
                or isinstance(session_seconds, bool)
                or not math.isfinite(float(session_seconds))
                or float(session_seconds) <= previous_time
            ):
                raise RuntimeError("LAB E5 timeline is not continuous and monotonic")
            rows.append(value)
            previous_source = source_index
            previous_time = float(session_seconds)
    if len(rows) != expected_count:
        raise RuntimeError("LAB E5 timeline count changed")
    return rows


def _infer(url: str, model: dict[str, Any], tensor: np.ndarray) -> tuple[np.ndarray, float]:
    contiguous = np.ascontiguousarray(tensor, dtype=np.float32)
    binary = contiguous.tobytes()
    header = {
        "inputs": [
            {
                "name": model["input_name"],
                "shape": list(contiguous.shape),
                "datatype": "FP32",
                "parameters": {"binary_data_size": len(binary)},
            }
        ],
        "outputs": [{"name": model["output_name"], "parameters": {"binary_data": True}}],
    }
    encoded_header = _canonical_json(header)
    request = urllib.request.Request(
        f"{url.rstrip('/')}/v2/models/{model['id']}/infer",
        data=encoded_header + binary,
        headers={
            "Content-Type": "application/octet-stream",
            "Inference-Header-Content-Length": str(len(encoded_header)),
        },
        method="POST",
    )
    started = time.perf_counter()
    with urllib.request.urlopen(request, timeout=60) as response:
        payload = response.read()
        header_length = int(response.headers["Inference-Header-Content-Length"])
    elapsed_ms = (time.perf_counter() - started) * 1000.0
    response_header = json.loads(payload[:header_length])
    output = response_header["outputs"][0]
    if output["name"] != model["output_name"] or output["datatype"] != "FP32":
        raise RuntimeError("LAB E5 Triton output descriptor changed")
    shape = tuple(int(value) for value in output["shape"])
    array = np.frombuffer(payload[header_length:], dtype="<f4")
    if array.size != math.prod(shape):
        raise RuntimeError("LAB E5 Triton output byte length changed")
    return array.reshape(shape), elapsed_ms


def _preprocess(image: np.ndarray, valid_mask: np.ndarray, profile: dict[str, Any]) -> np.ndarray:
    from PIL import Image

    height, width = image.shape[:2]
    shape = profile["model"]["input_shape"]
    target_height, target_width = int(shape[2]), int(shape[3])
    ratio = min(target_height / height, target_width / width)
    resized_width = int(width * ratio)
    resized_height = int(height * ratio)
    fill = int(profile["preprocessing"]["valid_fov_fill_value"])
    masked = np.where(valid_mask[..., None], image, fill).astype(np.uint8)
    resized = np.asarray(
        Image.fromarray(masked).resize((resized_width, resized_height), Image.Resampling.BILINEAR),
        dtype=np.uint8,
    )
    canvas = np.full((target_height, target_width, 3), fill, dtype=np.uint8)
    canvas[:resized_height, :resized_width] = resized[:, :, ::-1]
    return np.ascontiguousarray(canvas.transpose(2, 0, 1), dtype=np.float32)[None, ...]


def _decode_yolox(output: np.ndarray) -> np.ndarray:
    predictions = output.copy()
    grids: list[np.ndarray] = []
    strides: list[np.ndarray] = []
    for stride in (8, 16, 32):
        height = 640 // stride
        width = 640 // stride
        yv, xv = np.meshgrid(np.arange(height), np.arange(width), indexing="ij")
        grids.append(np.stack((xv, yv), axis=2).reshape(1, -1, 2))
        strides.append(np.full((1, height * width, 1), stride))
    grid = np.concatenate(grids, axis=1)
    expanded_strides = np.concatenate(strides, axis=1)
    predictions[..., :2] = (predictions[..., :2] + grid) * expanded_strides
    predictions[..., 2:4] = np.exp(predictions[..., 2:4]) * expanded_strides
    return predictions


def _box_iou(one: np.ndarray, many: np.ndarray) -> np.ndarray:
    if many.size == 0:
        return np.zeros((0,), dtype=np.float32)
    top_left = np.maximum(one[:2], many[:, :2])
    bottom_right = np.minimum(one[2:], many[:, 2:])
    intersection = np.prod(np.maximum(0.0, bottom_right - top_left), axis=1)
    one_area = max(0.0, float(one[2] - one[0])) * max(0.0, float(one[3] - one[1]))
    many_area = np.maximum(0.0, many[:, 2] - many[:, 0]) * np.maximum(
        0.0, many[:, 3] - many[:, 1]
    )
    union = one_area + many_area - intersection
    return np.divide(intersection, union, out=np.zeros_like(intersection), where=union > 0)


def _nms(
    boxes: np.ndarray,
    scores: np.ndarray,
    iou_threshold: float,
    containment_threshold: float,
) -> list[int]:
    order = scores.argsort()[::-1]
    keep: list[int] = []
    while order.size:
        index = int(order[0])
        keep.append(index)
        remaining = boxes[order[1:]]
        overlaps = _box_iou(boxes[index], remaining)
        top_left = np.maximum(boxes[index, :2], remaining[:, :2])
        bottom_right = np.minimum(boxes[index, 2:], remaining[:, 2:])
        intersection = np.prod(np.maximum(0.0, bottom_right - top_left), axis=1)
        remaining_area = np.maximum(0.0, remaining[:, 2] - remaining[:, 0]) * np.maximum(
            0.0, remaining[:, 3] - remaining[:, 1]
        )
        containment = np.divide(
            intersection,
            remaining_area,
            out=np.zeros_like(intersection),
            where=remaining_area > 0,
        )
        admitted = np.logical_and(
            overlaps <= iou_threshold,
            containment <= containment_threshold,
        )
        order = order[np.where(admitted)[0] + 1]
    return keep


def _valid_fraction(box: np.ndarray, integral: np.ndarray) -> tuple[float, bool, float]:
    height = integral.shape[0] - 1
    width = integral.shape[1] - 1
    x1 = int(np.clip(math.floor(float(box[0])), 0, width))
    y1 = int(np.clip(math.floor(float(box[1])), 0, height))
    x2 = int(np.clip(math.ceil(float(box[2])), 0, width))
    y2 = int(np.clip(math.ceil(float(box[3])), 0, height))
    area = float(max(0, x2 - x1) * max(0, y2 - y1))
    if area <= 0:
        return 0.0, False, 0.0
    inside = integral[y2, x2] - integral[y1, x2] - integral[y2, x1] + integral[y1, x1]
    center_x = int(np.clip(round((float(box[0]) + float(box[2])) / 2.0), 0, width - 1))
    center_y = int(np.clip(round((float(box[1]) + float(box[3])) / 2.0), 0, height - 1))
    center_inside = bool(
        integral[center_y + 1, center_x + 1]
        - integral[center_y, center_x + 1]
        - integral[center_y + 1, center_x]
        + integral[center_y, center_x]
    )
    return float(inside) / area, center_inside, area


def _detections(
    output: np.ndarray,
    profile: dict[str, Any],
    valid_mask: np.ndarray,
) -> tuple[list[dict[str, Any]], dict[str, int]]:
    prediction = _decode_yolox(output)[0]
    boxes = prediction[:, :4]
    boxes_xyxy = np.empty_like(boxes)
    boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2] / 2.0
    boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3] / 2.0
    boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2] / 2.0
    boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3] / 2.0
    source_height, source_width = valid_mask.shape
    ratio = min(640 / source_height, 640 / source_width)
    boxes_xyxy /= ratio
    class_scores = prediction[:, 4:5] * prediction[:, 5:]
    class_ids = class_scores.argmax(axis=1)
    scores = class_scores[np.arange(class_scores.shape[0]), class_ids]
    detection = profile["detection"]
    target_ids = set(int(value) for value in detection["target_class_ids"])
    candidate_mask = np.logical_and(
        scores >= float(detection["minimum_score"]),
        np.isin(class_ids, list(target_ids)),
    )
    candidate_boxes = boxes_xyxy[candidate_mask]
    candidate_scores = scores[candidate_mask]
    candidate_classes = class_ids[candidate_mask]
    integral = np.pad(valid_mask.astype(np.int64), ((1, 0), (1, 0))).cumsum(0).cumsum(1)
    result: list[dict[str, Any]] = []
    rejected = Counter()
    for class_id in sorted(target_ids):
        indices = np.where(candidate_classes == class_id)[0]
        if not indices.size:
            continue
        keep = _nms(
            candidate_boxes[indices],
            candidate_scores[indices],
            float(detection["nms_iou_threshold"]),
            float(detection["nms_containment_threshold"]),
        )
        for selected in indices[keep]:
            box = candidate_boxes[selected].copy()
            box[[0, 2]] = np.clip(box[[0, 2]], 0, source_width)
            box[[1, 3]] = np.clip(box[[1, 3]], 0, source_height)
            valid_fraction, center_inside, area = _valid_fraction(box, integral)
            if area < float(detection["minimum_box_area_pixels"]):
                rejected["small_box"] += 1
                continue
            if area / float(source_width * source_height) > float(
                detection["maximum_box_area_fraction"]
            ):
                rejected["large_box"] += 1
                continue
            if valid_fraction < float(detection["minimum_valid_fov_fraction"]):
                rejected["outside_valid_fov"] += 1
                continue
            if detection["require_center_inside_valid_fov"] and not center_inside:
                rejected["center_outside_valid_fov"] += 1
                continue
            result.append(
                {
                    "class_id": int(class_id),
                    "label": COCO_CLASSES[int(class_id)],
                    "score": round(float(candidate_scores[selected]), 9),
                    "bbox_xyxy": [round(float(value), 6) for value in box],
                    "valid_fov_fraction": round(valid_fraction, 6),
                }
            )
    result.sort(key=lambda item: (-float(item["score"]), int(item["class_id"])))
    return result, dict(rejected)


def _association(
    tracks: list[Track],
    detections: list[dict[str, Any]],
    threshold: float,
) -> tuple[list[tuple[int, int]], list[int], list[int]]:
    if not tracks or not detections:
        return [], list(range(len(tracks))), list(range(len(detections)))

    similarity = np.zeros((len(tracks), len(detections)), dtype=np.float64)
    for track_index, track in enumerate(tracks):
        matching = [
            index
            for index, detection in enumerate(detections)
            if int(detection["class_id"]) == track.class_id
        ]
        if matching:
            boxes = np.asarray([detections[index]["bbox_xyxy"] for index in matching])
            similarity[track_index, matching] = _box_iou(track.predicted_bbox(), boxes)
    try:
        from scipy.optimize import linear_sum_assignment

        rows, columns = linear_sum_assignment(1.0 - similarity)
        assignments = zip(rows.tolist(), columns.tolist(), strict=True)
    except ModuleNotFoundError:  # Local unit-test fallback; worker preflight requires SciPy.
        candidates = [
            (float(similarity[track_index, detection_index]), track_index, detection_index)
            for track_index in range(len(tracks))
            for detection_index in range(len(detections))
        ]
        used_tracks: set[int] = set()
        used_detections: set[int] = set()
        greedy: list[tuple[int, int]] = []
        for _score, track_index, detection_index in sorted(candidates, reverse=True):
            if track_index in used_tracks or detection_index in used_detections:
                continue
            used_tracks.add(track_index)
            used_detections.add(detection_index)
            greedy.append((track_index, detection_index))
        assignments = iter(greedy)
    matches: list[tuple[int, int]] = []
    matched_tracks: set[int] = set()
    matched_detections: set[int] = set()
    for track_index, detection_index in assignments:
        if similarity[track_index, detection_index] < threshold:
            continue
        matches.append((track_index, detection_index))
        matched_tracks.add(track_index)
        matched_detections.add(detection_index)
    return (
        matches,
        [index for index in range(len(tracks)) if index not in matched_tracks],
        [index for index in range(len(detections)) if index not in matched_detections],
    )


@dataclass
class Track:
    track_id: int
    class_id: int
    label: str
    bbox: np.ndarray
    score: float
    created_frame: int
    last_frame: int
    hits: int = 1
    age: int = 1
    time_since_update: int = 0
    velocity: np.ndarray = field(default_factory=lambda: np.zeros(4, dtype=np.float64))
    trail: list[tuple[float, float]] = field(default_factory=list)

    def predicted_bbox(self) -> np.ndarray:
        return self.bbox + self.velocity

    def update(self, detection: dict[str, Any], frame_index: int) -> None:
        incoming = np.asarray(detection["bbox_xyxy"], dtype=np.float64)
        delta = incoming - self.bbox
        self.velocity = self.velocity * 0.7 + delta * 0.3
        self.bbox = incoming
        self.score = float(detection["score"])
        self.last_frame = frame_index
        self.hits += 1
        self.age += 1
        self.time_since_update = 0
        self.trail.append(self.center())

    def miss(self) -> None:
        self.bbox = self.predicted_bbox()
        self.age += 1
        self.time_since_update += 1

    def center(self) -> tuple[float, float]:
        return (
            float((self.bbox[0] + self.bbox[2]) / 2.0),
            float((self.bbox[1] + self.bbox[3]) / 2.0),
        )


class TwoStageTracker:
    def __init__(self, configuration: dict[str, Any]) -> None:
        self.configuration = configuration
        self.tracks: list[Track] = []
        self.next_track_id = 1
        self.created = 0
        self.retired = 0

    def update(self, detections: list[dict[str, Any]], frame_index: int) -> list[Track]:
        high_threshold = float(self.configuration["high_score_threshold"])
        high = [item for item in detections if float(item["score"]) >= high_threshold]
        low = [item for item in detections if float(item["score"]) < high_threshold]
        primary, unmatched_tracks, unmatched_high = _association(
            self.tracks,
            high,
            float(self.configuration["primary_match_iou"]),
        )
        for track_index, detection_index in primary:
            self.tracks[track_index].update(high[detection_index], frame_index)

        remaining_tracks = [self.tracks[index] for index in unmatched_tracks]
        secondary, unmatched_remaining, _unmatched_low = _association(
            remaining_tracks,
            low,
            float(self.configuration["secondary_match_iou"]),
        )
        matched_secondary = {index for index, _ in secondary}
        for remaining_index, detection_index in secondary:
            remaining_tracks[remaining_index].update(low[detection_index], frame_index)
        for remaining_index, track in enumerate(remaining_tracks):
            if remaining_index not in matched_secondary:
                track.miss()

        new_threshold = float(self.configuration["new_track_threshold"])
        for detection_index in unmatched_high:
            detection = high[detection_index]
            if float(detection["score"]) < new_threshold:
                continue
            bbox = np.asarray(detection["bbox_xyxy"], dtype=np.float64)
            track = Track(
                track_id=self.next_track_id,
                class_id=int(detection["class_id"]),
                label=str(detection["label"]),
                bbox=bbox,
                score=float(detection["score"]),
                created_frame=frame_index,
                last_frame=frame_index,
                trail=[
                    (
                        float((bbox[0] + bbox[2]) / 2.0),
                        float((bbox[1] + bbox[3]) / 2.0),
                    )
                ],
            )
            self.next_track_id += 1
            self.created += 1
            self.tracks.append(track)

        buffer_frames = int(self.configuration["lost_track_buffer_frames"])
        active: list[Track] = []
        for track in self.tracks:
            if track.time_since_update <= buffer_frames:
                active.append(track)
            else:
                self.retired += 1
        self.tracks = active
        minimum_hits = int(self.configuration["minimum_confirmed_hits"])
        return [
            track
            for track in self.tracks
            if track.time_since_update == 0 and track.hits >= minimum_hits
        ]


def _track_document(track: Track) -> dict[str, Any]:
    return {
        "track_id": track.track_id,
        "class_id": track.class_id,
        "label": track.label,
        "score": round(track.score, 9),
        "bbox_xyxy": [round(float(value), 6) for value in track.bbox],
        "hits": track.hits,
        "age": track.age,
    }


def _duplicate_pairs(tracks: list[Track]) -> int:
    duplicates = 0
    for left_index, left in enumerate(tracks):
        for right in tracks[left_index + 1 :]:
            if left.class_id != right.class_id:
                continue
            if float(_box_iou(left.bbox, right.bbox[None, :])[0]) >= 0.8:
                duplicates += 1
    return duplicates


def _overlay(image: np.ndarray, tracks: list[Track], trail_length: int, line_width: int) -> Any:
    from PIL import Image, ImageDraw

    canvas = Image.fromarray(image)
    draw = ImageDraw.Draw(canvas)
    for track in tracks:
        color = _palette(500 + track.track_id)
        box = tuple(round(float(value)) for value in track.bbox)
        draw.rectangle(box, outline=color, width=line_width)
        points = [(round(x), round(y)) for x, y in track.trail[-trail_length:]]
        if len(points) > 1:
            draw.line(points, fill=color, width=max(1, line_width - 1))
        label = f"{track.label} #{track.track_id} {track.score:.0%}"
        text_box = draw.textbbox((box[0], box[1]), label)
        background = (
            text_box[0] - 3,
            text_box[1] - 2,
            text_box[2] + 3,
            text_box[3] + 2,
        )
        draw.rectangle(background, fill=color)
        draw.text((box[0], box[1]), label, fill=(0, 0, 0))
    return canvas


def _assert_disk_floor(path: Path, floor: int, frame: int) -> None:
    if floor < 0:
        raise RuntimeError("LAB E5 disk floor is invalid")
    free = shutil.disk_usage(path).free
    if floor and free < floor:
        raise RuntimeError(f"LAB E5 crossed the D-backed free-space floor at frame {frame}")


def _preflight(args: argparse.Namespace) -> int:
    job = _validate_job(args.job.resolve(strict=True))
    profile, profile_sha256 = _read_profile(args.profile)
    _validate_source(job, profile)
    valid_mask, valid_fov = _load_valid_fov(args.valid_fov_root, job, profile)
    model_files = _verify_model(profile, args.model_root)
    from scipy.optimize import linear_sum_assignment  # noqa: F401

    print(
        json.dumps(
            {
                "state": "preflight-ready",
                "job_id": job["job_id"],
                "profile_sha256": profile_sha256,
                "model_files": model_files,
                "valid_fov": valid_fov,
                "valid_pixels": int(valid_mask.sum()),
            },
            sort_keys=True,
        ),
        flush=True,
    )
    return 0


def _run(args: argparse.Namespace) -> int:
    from PIL import Image
    from scipy.optimize import linear_sum_assignment

    if not _valid_sha256(args.orchestrator_sha256):
        raise RuntimeError("LAB E5 orchestrator SHA-256 is invalid")
    if not args.triton_url.startswith("http://") or len(args.triton_url) > 256:
        raise RuntimeError("LAB E5 Triton URL is invalid")
    job = _validate_job(args.job.resolve(strict=True))
    profile, profile_sha256 = _read_profile(args.profile)
    _validate_source(job, profile)
    valid_mask, valid_fov = _load_valid_fov(args.valid_fov_root, job, profile)
    model_files = _verify_model(profile, args.model_root)
    frames_root = args.frames.resolve(strict=True)
    frame_paths = sorted(frames_root.glob("frame-*.png"))
    if not frame_paths:
        raise RuntimeError("LAB E5 decoded frame set is empty")
    if [path.name for path in frame_paths] != [
        f"frame-{index:06d}.png" for index in range(1, len(frame_paths) + 1)
    ]:
        raise RuntimeError("LAB E5 decoded frame sequence changed")
    timeline_path = args.timeline.resolve(strict=True)
    timeline_rows = _read_timeline(timeline_path, len(frame_paths))
    input_timeline = job["input"]["timeline"]
    if (
        float(timeline_rows[0]["session_seconds"]) < float(input_timeline["start_seconds"])
        or float(timeline_rows[-1]["session_seconds"]) > float(input_timeline["end_seconds"])
    ):
        raise RuntimeError("LAB E5 clip escaped the source timeline")

    output = args.output.resolve()
    if output.exists():
        raise RuntimeError("LAB E5 output must be absent")
    output.mkdir(mode=0o700, parents=True, exist_ok=False)
    overlays_root = output / "overlay-frames"
    overlays_root.mkdir(mode=0o700)
    _assert_disk_floor(output, args.free_bytes_floor, 0)

    tracker = TwoStageTracker(profile["tracking"])
    linear_sum_assignment(np.zeros((1, 1), dtype=np.float64))
    latency = {
        name: []
        for name in (
            "image_decode_ms",
            "preprocess_ms",
            "triton_request_ms",
            "postprocess_ms",
            "tracking_ms",
            "overlay_write_ms",
            "end_to_end_ms",
        )
    }
    detection_labels: Counter[str] = Counter()
    track_observation_labels: Counter[str] = Counter()
    rejection_reasons: Counter[str] = Counter()
    unique_track_ids: set[int] = set()
    per_track_observations: Counter[int] = Counter()
    duplicate_pairs = 0
    frames_with_tracks = 0
    metadata_path = output / "frames.jsonl"
    telemetry_path = output / "gpu-telemetry.jsonl"
    resource_before = _resource_snapshot()
    disk_before = shutil.disk_usage(output).free
    started = time.perf_counter()

    with Image.open(frame_paths[0]) as opened:
        warm_image = np.asarray(opened.convert("RGB"), dtype=np.uint8)
    warm_tensor = _preprocess(warm_image, valid_mask, profile)
    _warm_output, _warm_ms = _infer(args.triton_url, profile["model"], warm_tensor)
    del _warm_output, _warm_ms, warm_tensor

    with (
        metadata_path.open("x", encoding="utf-8", newline="\n") as metadata_stream,
        telemetry_path.open("x", encoding="utf-8", newline="\n") as telemetry_stream,
        _GpuTelemetry(telemetry_stream, args.telemetry_interval_seconds) as telemetry,
    ):
        for frame_index, (frame_path, timeline_row) in enumerate(
            zip(frame_paths, timeline_rows, strict=True)
        ):
            frame_started = time.perf_counter()
            decode_started = time.perf_counter()
            with Image.open(frame_path) as opened:
                image = np.asarray(opened.convert("RGB"), dtype=np.uint8)
            latency["image_decode_ms"].append((time.perf_counter() - decode_started) * 1000.0)
            if image.shape != (600, 800, 3):
                raise RuntimeError("LAB E5 input resolution changed")

            preprocess_started = time.perf_counter()
            tensor = _preprocess(image, valid_mask, profile)
            latency["preprocess_ms"].append(
                (time.perf_counter() - preprocess_started) * 1000.0
            )
            output_tensor, request_ms = _infer(args.triton_url, profile["model"], tensor)
            latency["triton_request_ms"].append(request_ms)

            postprocess_started = time.perf_counter()
            detections, rejected = _detections(output_tensor, profile, valid_mask)
            latency["postprocess_ms"].append(
                (time.perf_counter() - postprocess_started) * 1000.0
            )
            for reason, count in rejected.items():
                rejection_reasons[reason] += count
            detection_labels.update(str(item["label"]) for item in detections)

            tracking_started = time.perf_counter()
            tracks = tracker.update(detections, frame_index)
            latency["tracking_ms"].append((time.perf_counter() - tracking_started) * 1000.0)
            duplicate_pairs += _duplicate_pairs(tracks)
            if tracks:
                frames_with_tracks += 1
            for track in tracks:
                unique_track_ids.add(track.track_id)
                per_track_observations[track.track_id] += 1
                track_observation_labels[track.label] += 1

            write_started = time.perf_counter()
            overlay = _overlay(
                image,
                tracks,
                int(profile["overlay"]["trail_length"]),
                int(profile["overlay"]["line_width"]),
            )
            overlay.save(
                overlays_root / f"frame-{frame_index + 1:06d}.png",
                format="PNG",
                optimize=False,
            )
            metadata_stream.write(
                json.dumps(
                    {
                        "schema_version": FRAME_SCHEMA,
                        "frame_index": frame_index,
                        "sequence": frame_index + 1,
                        "source_frame_index": timeline_row["source_frame_index"],
                        "source_sequence": timeline_row["source_sequence"],
                        "session_seconds": round(float(timeline_row["session_seconds"]), 9),
                        "detections": detections,
                        "tracks": [_track_document(track) for track in tracks],
                    },
                    ensure_ascii=False,
                    sort_keys=True,
                    separators=(",", ":"),
                    allow_nan=False,
                )
                + "\n"
            )
            latency["overlay_write_ms"].append(
                (time.perf_counter() - write_started) * 1000.0
            )
            latency["end_to_end_ms"].append((time.perf_counter() - frame_started) * 1000.0)
            completed = frame_index + 1
            if completed % 100 == 0 or completed == len(frame_paths):
                metadata_stream.flush()
                telemetry_stream.flush()
                _assert_disk_floor(output, args.free_bytes_floor, completed)
                print(
                    json.dumps(
                        {
                            "phase": "tracking",
                            "frames_processed": completed,
                            "frames_total": len(frame_paths),
                            "active_tracks": len(tracker.tracks),
                            "free_bytes": shutil.disk_usage(output).free,
                        },
                        sort_keys=True,
                    ),
                    flush=True,
                )
        metadata_stream.flush()
        os.fsync(metadata_stream.fileno())

    elapsed = time.perf_counter() - started
    resource_after = _resource_snapshot()
    track_lengths = list(per_track_observations.values())
    report = {
        "schema_version": REPORT_SCHEMA,
        "run_id": f"{job['job_id']}-e5-yolox-bytetrack-style-v1",
        "created_at_utc": datetime.now(UTC)
        .isoformat(timespec="milliseconds")
        .replace("+00:00", "Z"),
        "state": "inference-complete-awaiting-publication",
        "ground_truth": False,
        "input": {
            "job_id": job["job_id"],
            "input_sha256": job["input_sha256"],
            "session_id": job["input"]["session_id"],
            "source_id": job["input"]["source_id"],
            "codec_epoch": job["input"]["codec_epoch"],
            "source_frame_count": job["input"]["segment_count"],
            "clip_frame_count": len(frame_paths),
            "source_start_frame_index": timeline_rows[0]["source_frame_index"],
            "source_end_frame_index": timeline_rows[-1]["source_frame_index"],
            "timeline_start_seconds": timeline_rows[0]["session_seconds"],
            "timeline_end_seconds": timeline_rows[-1]["session_seconds"],
            "timeline_sha256": _sha256(timeline_path),
        },
        "calibration": {
            "content_identity_sha256": profile["source"]["calibration_sha256"],
            "camera_slot": profile["source"]["calibration_slot"],
        },
        "configuration": {
            "pipeline": PIPELINE_ID,
            "profile_sha256": profile_sha256,
            "profile": profile,
            "valid_fov": valid_fov,
            "runner_sha256": _sha256(Path(__file__).resolve(strict=True)),
            "orchestrator_sha256": args.orchestrator_sha256,
            "container_image": args.container_image,
        },
        "models": {"detector": profile["model"], "files": model_files},
        "runtime": {
            "hostname": platform.node(),
            "platform": platform.platform(),
            "python": platform.python_version(),
            "numpy": np.__version__,
            "scipy": importlib.metadata.version("scipy"),
        },
        "metrics": {
            "frames_expected": len(frame_paths),
            "frames_processed": len(frame_paths),
            "frames_failed": 0,
            "frames_skipped": 0,
            "inference_wall_seconds": round(elapsed, 6),
            "inference_frames_per_second": round(len(frame_paths) / elapsed, 6),
            "latency_ms": {name: _percentiles(values) for name, values in latency.items()},
            "detections": int(sum(detection_labels.values())),
            "detections_by_label": dict(sorted(detection_labels.items())),
            "detection_rejections": dict(sorted(rejection_reasons.items())),
            "unique_confirmed_tracks": len(unique_track_ids),
            "track_observations": int(sum(track_observation_labels.values())),
            "track_observations_by_label": dict(sorted(track_observation_labels.items())),
            "frames_with_confirmed_tracks": frames_with_tracks,
            "confirmed_track_length_frames": _percentiles(track_lengths),
            "same_class_duplicate_pairs_iou_ge_0_8": duplicate_pairs,
            "tracker_tracks_created": tracker.created,
            "tracker_tracks_retired": tracker.retired,
            "process_peak_rss_mib": round(
                resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024,
                3,
            ),
            "resource_delta": _resource_delta(resource_before, resource_after),
            "gpu_telemetry": telemetry.summary(),
            "disk": {
                "free_bytes_before_inference": disk_before,
                "free_bytes_after_inference": shutil.disk_usage(output).free,
                "free_bytes_floor": args.free_bytes_floor,
            },
        },
        "limitations": [
            "No human-reviewed tracking ground truth; ID switches cannot be measured.",
            "Generic COCO-80 detector filtered to people and mobility classes.",
            "IoU-only tracking has no appearance ReID or camera-motion compensation.",
            "Qualification clip is not a full-session or live-stream result.",
        ],
    }
    _write_json(output / "run-report.partial.json", report)
    print(
        json.dumps(
            {
                "state": report["state"],
                "frames": len(frame_paths),
                "inference_seconds": round(elapsed, 6),
                "unique_tracks": len(unique_track_ids),
            },
            sort_keys=True,
        ),
        flush=True,
    )
    return 0


def _finalize(args: argparse.Namespace) -> int:
    output = args.output.resolve(strict=True)
    video = args.video.resolve(strict=True)
    contact_sheet = args.contact_sheet.resolve(strict=True)
    if video.parent != output or contact_sheet.parent != output:
        raise RuntimeError("LAB E5 publication artifacts escaped the result root")
    partial_path = output / "run-report.partial.json"
    frames_path = output / "frames.jsonl"
    telemetry_path = output / "gpu-telemetry.jsonl"
    partial = _read_object(partial_path)
    metrics = partial.get("metrics")
    if (
        partial.get("schema_version") != REPORT_SCHEMA
        or partial.get("state") != "inference-complete-awaiting-publication"
        or not isinstance(metrics, dict)
        or metrics.get("frames_expected") != metrics.get("frames_processed")
        or metrics.get("frames_failed") != 0
        or metrics.get("frames_skipped") != 0
    ):
        raise RuntimeError("LAB E5 inference result is incomplete")
    timings = (args.extract_seconds, args.encode_seconds, args.wall_seconds)
    if any(value <= 0 for value in timings):
        raise RuntimeError("LAB E5 publication timing is invalid")
    disk_points = (
        args.disk_free_before_bytes,
        args.disk_free_post_extract_bytes,
        args.disk_free_post_inference_bytes,
        args.disk_free_post_artifacts_bytes,
    )
    if any(value < args.disk_floor_bytes for value in disk_points):
        raise RuntimeError("LAB E5 publication crossed its D: free-space floor")

    identity = {
        "schema_version": IDENTITY_SCHEMA,
        "job_id": partial["input"]["job_id"],
        "input_sha256": partial["input"]["input_sha256"],
        "clip": {
            key: partial["input"][key]
            for key in (
                "clip_frame_count",
                "source_start_frame_index",
                "source_end_frame_index",
                "timeline_start_seconds",
                "timeline_end_seconds",
                "timeline_sha256",
            )
        },
        "calibration": partial["calibration"],
        "configuration": partial["configuration"],
        "models": partial["models"],
        "publication": {
            "video_encoder": args.encoder,
            "video_media_type": "video/mp4",
            "scope": "qualification-clip-only",
        },
    }
    identity_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
    result_id = f"e5-tracking-{identity_sha256}"
    final_report = {
        **partial,
        "state": "published-qualification",
        "result_id": result_id,
        "publication": {
            "extract_seconds": round(args.extract_seconds, 6),
            "encode_seconds": round(args.encode_seconds, 6),
            "wall_seconds": round(args.wall_seconds, 6),
            "end_to_end_frames_per_second": round(
                int(metrics["frames_processed"]) / args.wall_seconds,
                6,
            ),
            "encoder": args.encoder,
            "disk": {
                "free_bytes_before": args.disk_free_before_bytes,
                "free_bytes_post_extract": args.disk_free_post_extract_bytes,
                "free_bytes_post_inference": args.disk_free_post_inference_bytes,
                "free_bytes_post_artifacts": args.disk_free_post_artifacts_bytes,
                "free_bytes_floor": args.disk_floor_bytes,
                "working_set_reserve_bytes": args.working_set_reserve_bytes,
            },
        },
    }
    report_path = output / "run-report.json"
    _write_json(report_path, final_report)
    artifacts = [
        _artifact(video, "tracking-overlay-video", "video/mp4"),
        _artifact(frames_path, "tracking-frame-metadata", "application/x-ndjson", FRAME_SCHEMA),
        _artifact(telemetry_path, "worker-gpu-telemetry", "application/x-ndjson"),
        _artifact(contact_sheet, "tracking-contact-sheet", "image/png"),
        _artifact(report_path, "tracking-run-report", "application/json", REPORT_SCHEMA),
    ]
    result = {
        "schema_version": RESULT_SCHEMA,
        "result_id": result_id,
        "identity_sha256": identity_sha256,
        "identity": identity,
        "created_at_utc": final_report["created_at_utc"],
        "job_id": partial["input"]["job_id"],
        "input_sha256": partial["input"]["input_sha256"],
        "session_id": partial["input"]["session_id"],
        "source_id": partial["input"]["source_id"],
        "timestamp_basis": "session-time-seconds",
        "frames_processed": metrics["frames_processed"],
        "ground_truth": False,
        "publication_scope": "qualification-clip-only",
        "artifacts": artifacts,
    }
    _write_json(output / "result.json", result)
    partial_path.unlink()
    print(json.dumps({"result_id": result_id, "identity_sha256": identity_sha256}))
    return 0


def main() -> int:
    args = _arguments()
    if args.command == "preflight":
        return _preflight(args)
    if args.command == "run":
        return _run(args)
    return _finalize(args)


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