"""Conformance suite runs against the shipped Fakes (D-F3 + §10).

This eats our own dog food: the same suite adapter authors will run
against real engines is run here against the Fakes. If a scenario
fails on a Fake, either the Fake is wrong or the contract is wrong
— in either case we want to know immediately.

When the libvirt + firecracker adapters land, their integration test
suites import the same module and call the same suites.
"""

from __future__ import annotations

from mgf.vm.core.conformance import (
    device_conformance_suite,
    guest_agent_conformance_suite,
    host_disk_conformance_suite,
    hypervisor_conformance_suite,
    metrics_conformance_suite,
    network_conformance_suite,
    storage_conformance_suite,
)
from mgf.vm.core.fakes import (
    FakeDeviceBackend,
    FakeGuestAgentBackend,
    FakeHostDiskBackend,
    FakeHypervisorBackend,
    FakeMetricsBackend,
    FakeNetworkBackend,
    FakeStorageBackend,
)
from mgf.vm.core.ids import DomainId


def test_hypervisor_conformance_against_fake() -> None:
    """CONF-H-01..03 pass against FakeHypervisorBackend."""
    suite = hypervisor_conformance_suite(FakeHypervisorBackend())
    suite.run_all()
    # All three scenarios green, no skips.
    failures = [r for r in suite.results if not r.passed]
    assert failures == [], (
        f"hypervisor conformance failed: {[(r.scenario_id, r.error) for r in failures]}"
    )


def test_network_observation_conformance_scenario() -> None:
    """CONF-H-11 (Wave-B, D-G14) — host-network observation on the Fake."""
    suite = hypervisor_conformance_suite(FakeHypervisorBackend())
    result = suite.run_one("CONF-H-11")
    assert result.passed is True, result.error
    assert result.scenario_id == "CONF-H-11"


def test_metrics_conformance_scenario() -> None:
    """CONF-M-01 (Wave-B, D-G13) — sample_metrics on the OPTIONAL MetricsBackend."""
    d = DomainId("conf-m-01")
    suite = metrics_conformance_suite(
        FakeMetricsBackend(known_domains=[d]),
        known_domain=d,
    )
    result = suite.run_one("CONF-M-01")
    assert result.passed is True, result.error
    assert result.scenario_id == "CONF-M-01"


def test_guest_agent_conformance_scenario() -> None:
    """CONF-G-01 (Wave-R6, D-G19) — guest ping/os-info/interfaces on the
    OPTIONAL GuestAgentBackend."""
    d = DomainId("conf-g-01")
    suite = guest_agent_conformance_suite(
        FakeGuestAgentBackend(known_domains=[d]),
        known_domain=d,
    )
    result = suite.run_one("CONF-G-01")
    assert result.passed is True, result.error
    assert result.scenario_id == "CONF-G-01"


def test_host_disk_conformance_scenario() -> None:
    """CONF-O-01 (Wave-R4, D-G18) — disk round-trip on the OPTIONAL HostDiskBackend."""
    backend = FakeHostDiskBackend()
    backend._put_image("/img/vda.qcow2", content=b"root-disk-bytes")
    backend._put_image("/img/vdb.raw", content=b"data-disk-bytes", fmt="raw")
    suite = host_disk_conformance_suite(
        backend,
        sources={"vda": "/img/vda.qcow2", "vdb": "/img/vdb.raw"},
        workdir="/work",
    )
    result = suite.run_one("CONF-O-01")
    assert result.passed is True, result.error
    assert result.scenario_id == "CONF-O-01"


def test_network_conformance_scenario() -> None:
    """CONF-N-01 (Wave-R3, D-G15) — define/start/stop/delete on NetworkBackend."""
    hv = FakeHypervisorBackend()
    suite = network_conformance_suite(FakeNetworkBackend(hv), observer=hv)
    result = suite.run_one("CONF-N-01")
    assert result.passed is True, result.error
    assert result.scenario_id == "CONF-N-01"


def test_storage_conformance_against_fake() -> None:
    """CONF-S-01, CONF-S-03 pass against FakeStorageBackend."""
    suite = storage_conformance_suite(FakeStorageBackend())
    suite.run_all()
    failures = [r for r in suite.results if not r.passed]
    assert failures == [], (
        f"storage conformance failed: {[(r.scenario_id, r.error) for r in failures]}"
    )


def test_device_conformance_against_fake() -> None:
    """CONF-D-01, CONF-D-04 pass against FakeDeviceBackend."""
    suite = device_conformance_suite(FakeDeviceBackend.with_default_devices())
    suite.run_all()
    failures = [r for r in suite.results if not r.passed]
    assert failures == [], (
        f"device conformance failed: {[(r.scenario_id, r.error) for r in failures]}"
    )


def test_run_one_for_targeted_debugging() -> None:
    """Adapter authors can run individual scenarios when debugging."""
    suite = hypervisor_conformance_suite(FakeHypervisorBackend())
    result = suite.run_one("CONF-H-01")
    assert result.passed is True
    assert result.scenario_id == "CONF-H-01"


def test_summary_format() -> None:
    """``summary()`` produces a human-readable one-liner."""
    suite = hypervisor_conformance_suite(FakeHypervisorBackend())
    suite.run_all()
    summary = suite.summary()
    assert "passed" in summary
    assert "failed" in summary


def test_unknown_scenario_raises_keyerror() -> None:
    """Asking for a non-existent scenario fails fast."""
    import pytest

    suite = hypervisor_conformance_suite(FakeHypervisorBackend())
    with pytest.raises(KeyError):
        suite.run_one("CONF-H-99-nonexistent")
