"""Guest-agent conformance scenarios (CONF-G-* in ``contracts.md`` §10).

Exercise the OPTIONAL :class:`~mgf.vm.core.contracts.GuestAgentBackend`
Protocol (Wave-R6, D-G19). Each scenario is a callable taking a
``GuestAgentBackend`` instance and either passing (return) or failing (raise).
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from mgf.vm.core.contracts import GuestNic, GuestOsInfo
from mgf.vm.core.exceptions import DomainNotFound
from mgf.vm.core.ids import DomainId

if TYPE_CHECKING:
    from mgf.vm.core.contracts import GuestAgentBackend


def guest_observation(adapter: GuestAgentBackend, *, known: DomainId) -> None:
    """CONF-G-01 — guest ping / os-info / interfaces on the OPTIONAL backend.

    A read-only observation on the OPTIONAL :class:`GuestAgentBackend`:
    against a known domain whose agent is reachable (the caller arranges it —
    the Fake seeds it reachable; a real adapter passes a live agent-running
    domain) assert the neutral shapes — ``guest_ping`` is ``True``,
    ``guest_os_info`` is a :class:`GuestOsInfo`, ``guest_interfaces`` is a
    tuple of :class:`GuestNic`. Reads are idempotent (they do not mutate the
    guest). Every method on an unknown domain raises ``DomainNotFound``.
    """
    assert adapter.guest_ping(known) is True, "agent on the known domain must be reachable"

    os_info = adapter.guest_os_info(known)
    assert isinstance(os_info, GuestOsInfo), "guest_os_info must return GuestOsInfo"

    nics = adapter.guest_interfaces(known)
    assert isinstance(nics, tuple), "guest_interfaces must return a tuple"
    assert all(isinstance(n, GuestNic) for n in nics), "each interface is a GuestNic"

    # Idempotent: a second read of the same domain is also valid.
    adapter.guest_interfaces(known)

    # Every method on an unknown domain raises DomainNotFound.
    unknown = DomainId("conf-g-01-no-such-domain")
    for call in (
        lambda: adapter.guest_ping(unknown),
        lambda: adapter.guest_os_info(unknown),
        lambda: adapter.guest_interfaces(unknown),
    ):
        raised = False
        try:
            call()
        except DomainNotFound:
            raised = True
        assert raised, "guest-agent reads of an unknown domain must raise DomainNotFound"


__all__ = ["guest_observation"]
