"""Evaluate several typed observables from one Digital final state.

An ``ObservableSet`` requests a batch without rerunning the program for each
operator. Exact state evaluation preserves expectation, variance, estimator
kind, sample count, and source identity in one typed result.
"""

from __future__ import annotations

import json

from cascaqit import Circuit, LocalBackend, ObservableSet, PauliX, PauliZ, PauliZZ


def main() -> None:
    """Prepare a Bell state and evaluate X, Z, and ZZ together."""
    circuit = Circuit(2, program_id="lesson.digital.observables").h(0).cx(0, 1)
    observables = ObservableSet((PauliZ("q0"), PauliX("q0"), PauliZZ("q0", "q1")))
    result = (
        LocalBackend(seed=204).run(circuit, shots=32, observables=observables).result()
    )
    batch = result.observable_batch
    if batch is None:
        raise RuntimeError("Requested observable batch was not returned.")

    payload = {
        "track": "digital_developer",
        "level": "advanced",
        "lesson": "observable_batch",
        "facts": {
            "source_kind": batch.source_kind.value,
            "observable_names": [item.name for item in batch.items],
            "expectations": [round(item.expectation, 10) for item in batch.items],
            "estimator_kinds": [item.estimator_kind.value for item in batch.items],
            "source_hash_matches": batch.source_hash == result.metadata["state_hash"],
        },
        "boundaries": {
            "hardware_execution": False,
            "cloud_execution": False,
            "network_accessed": False,
            "credentials_loaded": False,
        },
    }
    print(json.dumps(payload, sort_keys=True))


if __name__ == "__main__":
    main()
