"""Tests for :mod:`mgf.vm.core.security.isolation.checks.hostdev` (MA-A2.4)."""

from __future__ import annotations

from _isolation_xml import domain_with, parsed

from mgf.vm.core.security.isolation.checks.hostdev import (
    hostdev_no_mdev,
    hostdev_no_pci,
    hostdev_no_usb,
)
from mgf.vm.core.security.isolation.context import AnalysisContext
from mgf.vm.core.security.isolation.types import FixKind, IsolationCategory


def _ctx(*body: str) -> AnalysisContext:
    return AnalysisContext(
        domain_xml=parsed(domain_with(*body)),
        vm_name="t",
    )


def _hostdev(dev_type: str, alias: str = "") -> str:
    alias_xml = f"<alias name='{alias}'/>" if alias else ""
    return (
        f"<hostdev mode='subsystem' type='{dev_type}'>"
        f"<source><address bus='0x01' slot='0x00' function='0x0'/></source>"
        f"{alias_xml}"
        f"</hostdev>"
    )


class TestHostdevNoPci:
    def test_passes_when_absent(self) -> None:
        f = hostdev_no_pci(_ctx())
        assert f.passing is True

    def test_fails_when_pci_present(self) -> None:
        f = hostdev_no_pci(_ctx(_hostdev("pci", alias="hostdev0")))
        assert f.passing is False
        assert f.category is IsolationCategory.BLOCKING
        assert f.fix_kind is FixKind.AUTO_FIX
        assert f.fix_executor == "strip.hostdev.pci"

    def test_ignores_usb_hostdev(self) -> None:
        f = hostdev_no_pci(_ctx(_hostdev("usb")))
        assert f.passing is True


class TestHostdevNoUsb:
    def test_passes_when_absent(self) -> None:
        f = hostdev_no_usb(_ctx())
        assert f.passing is True

    def test_fails_when_usb_present(self) -> None:
        f = hostdev_no_usb(_ctx(_hostdev("usb", alias="usb0")))
        assert f.passing is False
        assert f.fix_executor == "strip.hostdev.usb"

    def test_ignores_pci_hostdev(self) -> None:
        f = hostdev_no_usb(_ctx(_hostdev("pci")))
        assert f.passing is True


class TestHostdevNoMdev:
    def test_passes_when_absent(self) -> None:
        f = hostdev_no_mdev(_ctx())
        assert f.passing is True

    def test_fails_when_mdev_present(self) -> None:
        f = hostdev_no_mdev(_ctx(_hostdev("mdev", alias="mdev0")))
        assert f.passing is False
        assert f.fix_executor == "strip.hostdev.mdev"
