"""Durable SDS annotation lifecycle integration contract."""

from __future__ import annotations

import signal_dataset as sds

from rfgen.annotation.inference import InferenceResponse
from rfgen.annotation.run import AnnotationRunConfig, run_annotation
from tests.unit.annotation.annotation_testing import ProseClient, annotation_dataset


class _CountingProseClient(ProseClient):
    provider_name = "counting-test"
    model_id = "counting-caption"

    def __init__(self) -> None:
        self.request_count = 0

    def complete(
        self,
        *,
        prompt,
        json_schema=None,
        max_tokens=None,
        request_id=None,
        template_id=None,
        run_id=None,
    ) -> InferenceResponse:
        self.request_count += 1
        return super().complete(
            prompt=prompt,
            json_schema=json_schema,
            max_tokens=max_tokens,
            request_id=request_id,
            template_id=template_id,
            run_id=run_id,
        )


def test_a_published_overlay_reopens_with_its_values_and_provenance_unchanged(
    tmp_path,
) -> None:
    """Publish once, reopen, and compare by direct equality.

    Compared value-for-value rather than by a stored digest, which is what this
    repository prescribes: a reviewer reading a diff sees *what* changed, where a
    digest says only that something did.

    This test was previously named for resuming "without a second request".
    There is no resume: `rfgen annotate submit` prepares the whole corpus and
    publishes atomically, and a killed run is rerun. Reopening a published set
    issues no request because reading is not annotating, which is worth
    asserting but is not resumption.
    """

    dataset = annotation_dataset(tmp_path, count=1)
    client = _CountingProseClient()
    published = run_annotation(
        AnnotationRunConfig(
            dataset_uri=dataset.root,
            annotation_set="scene_reports",
            publication_id="integration-run",
            template_id="scene_report.declared.v1",
            annotator="rfgen.annotation.reference.scene_report:SceneReportAnnotator",
            run_id="integration_run",
            model=client.model_id,
            inference={"provider": client.provider_name, "concurrency": 1},
        ),
        clients=(client,),
    )

    assert client.request_count == 1
    assert published[0].status is sds.AnnotationStatus.SUCCESS

    reopened = sds.open(dataset.root).annotations["scene_reports"]

    assert reopened[0].values == published[0].values
    assert reopened[0].provenance == published[0].provenance
    assert reopened.publication_id == "integration-run"
    assert client.request_count == 1, "reopening a published set must not re-annotate"


def test_a_reopened_row_carries_both_halves_and_says_the_prose_is_unverified(
    tmp_path,
) -> None:
    """What survives a publish-and-reopen is the whole contract, not just the prose."""

    dataset = annotation_dataset(tmp_path, count=1)
    run_annotation(
        AnnotationRunConfig(
            dataset_uri=dataset.root,
            annotation_set="scene_reports",
            publication_id="halves-run",
            template_id="scene_report.declared.v1",
            annotator="rfgen.annotation.reference.scene_report:SceneReportAnnotator",
            run_id="halves_run",
            model="test-scene-report",
            inference={"provider": "test", "concurrency": 1},
        ),
        clients=(ProseClient(),),
    )

    row = sds.open(dataset.root).annotations["scene_reports"][0]

    assert set(row.values) == {"output", "claims"}
    assert row.values["output"]["expert_summary"]
    assert row.values["claims"]["signals"]
    assert row.provenance["prose_verification"] == "not_performed"
