"""Capability descriptors per ``contracts.md`` §3.5 / §4 / §5.

Adapters report what they can do via ``capabilities()``. The scheduler
uses this for placement decisions; the conformance suite uses it to
skip tests for unsupported features (so a Firecracker adapter can
honestly report "no live migration" and the suite's CONF-H migration
tests skip themselves).

These are frozen dataclasses (DP-03). Adapter authors construct them
once and return them from every ``capabilities()`` call.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from mgf.vm.core.domain import IsolationLevel


@dataclass(frozen=True, slots=True)
class HypervisorCapabilities:
    """What this ``HypervisorBackend`` instance supports.

    See ``contracts.md`` §3.5 ``capabilities()``.
    """

    engine: str
    """e.g., ``"libvirt-kvm"``, ``"firecracker"``."""

    engine_version: str

    supports_live_migration: bool
    """Live migration of running VMs between hosts."""

    supports_memory_snapshots: bool
    """Snapshot including running memory state, not just disks."""

    supports_device_attach_live: bool
    """Attach passthrough devices to a running VM."""

    max_cpus: int

    max_memory_bytes: int

    cpu_features: frozenset[str] = field(default_factory=frozenset)
    """Host CPU features (used by the scheduler for migration compatibility)."""

    storage_pool_types: frozenset[str] = field(default_factory=frozenset)
    """e.g., ``{"dir", "lvm", "rbd", "nfs"}``."""

    isolation_profiles: frozenset[IsolationLevel] = field(default_factory=frozenset)


@dataclass(frozen=True, slots=True)
class StorageCapabilities:
    """What this ``StorageBackend`` instance supports."""

    engine: str
    engine_version: str

    supports_pool_types: frozenset[str] = field(default_factory=frozenset)
    supports_formats: frozenset[str] = field(default_factory=frozenset)
    """e.g., ``{"qcow2", "raw"}``."""

    supports_shrink: bool = False
    """Some engines refuse online shrink (CONF-S-05 capability-gates against this)."""

    supports_thin_provisioning: bool = True


@dataclass(frozen=True, slots=True)
class DeviceCapabilities:
    """What this ``DeviceBackend`` instance supports.

    For Linux hosts using ``mgf-hrb``, all flags are typically true.
    For Windows hosts wrapping DDA directly (hypothetical, per
    ARCHITECTURE.md §10), guarantees differ — the broker's
    ghost-free / capability-scoping is Linux-only.
    """

    backend: str
    """e.g., ``"mgf-hrb"``, ``"dda"``."""

    backend_version: str

    supports_pci: bool = True
    supports_usb: bool = True
    supports_gpu_mdev: bool = False
    """vGPU mediated devices (Intel GVT-g, NVIDIA vGPU)."""

    supports_sr_iov: bool = True

    supports_lease_transfer: bool = True
    """Lease handoff between hosts (architecture §6) — required for live
    migration with passthrough."""

    fenced_by_liveness: bool = True
    """The broker reclaims devices when the holding client dies
    (``mgf-hrb`` G3). False for adapters that don't have this guarantee."""

    capability_scoped: bool = True
    """Devices outside the host's attenuated capability cannot be claimed."""


__all__ = [
    "DeviceCapabilities",
    "HypervisorCapabilities",
    "StorageCapabilities",
]
