#!/usr/bin/env python3
"""Link attributed, reviewed visual observations to existing EDL events."""

from __future__ import annotations

import argparse
import json
from pathlib import Path

ALLOWED_CLASSES = {
    "technical_observation",
    "human_or_vision_observation",
    "heuristic",
    "unresolved_claim",
}


def fail(code: str, message: str) -> int:
    print(json.dumps({"ok": False, "error": {"code": code, "message": message}}))
    return 2


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("manifest")
    parser.add_argument("edl")
    parser.add_argument("--output", required=True)
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args()
    try:
        manifest = json.loads(Path(args.manifest).read_text())
        edl = json.loads(Path(args.edl).read_text())
        output = Path(args.output)
    except (OSError, json.JSONDecodeError) as exc:
        return fail("invalid_input", str(exc))
    if output.exists():
        return fail("output_exists", "output already exists")
    review = manifest.get("review", {})
    if review.get("status") != "reviewed" or not review.get("reviewer"):
        return fail(
            "review_evidence_missing",
            "manifest needs an attributed reviewed status before EDL import",
        )
    observations = review.get("observations")
    if not isinstance(observations, list) or not observations:
        return fail("review_evidence_missing", "manifest has no reviewed observations")
    events = {event.get("id"): event for event in edl.get("events", [])}
    imported = 0
    for observation in observations:
        event_id = observation.get("edl_event_id")
        evidence_class = observation.get("evidence_class")
        if event_id not in events:
            return fail("event_not_found", f"observation targets unknown EDL event: {event_id}")
        if evidence_class not in ALLOWED_CLASSES:
            return fail("invalid_evidence_class", f"unsupported evidence class: {evidence_class}")
        if observation.get("coverage_scope") in {"whole_asset", "all_unsampled_intervals"}:
            return fail(
                "unsupported_coverage_claim",
                "sparse samples cannot establish whole-asset or unsampled absence",
            )
        if (
            not observation.get("id")
            or not observation.get("observation")
            or not observation.get("artifact_refs")
        ):
            return fail(
                "invalid_observation", "each observation needs id, text, and artifact references"
            )
        events[event_id].setdefault("evidence", []).append(
            {
                "type": "visual_review",
                "packet_id": manifest.get("packet_id"),
                "observation_id": observation["id"],
                "asset_id": manifest.get("asset_id"),
                "reviewer": review["reviewer"],
                "evidence_class": evidence_class,
                "confidence": observation.get("confidence"),
                "editorial_consequence": observation.get("editorial_consequence"),
                "artifact_refs": observation["artifact_refs"],
                "coverage_scope": observation.get("coverage_scope", "sampled_artifacts_only"),
            }
        )
        imported += 1
    output.write_text(json.dumps(edl, indent=2) + "\n")
    print(
        json.dumps(
            {
                "ok": True,
                "output": str(output),
                "imported_observations": imported,
                "executed_media_change": False,
            }
        )
    )
    return 0


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