"""Tests for :mod:`mgf.vm.core.configurator.display` (pure planner)."""

from __future__ import annotations

import xml.etree.ElementTree as ET

import pytest

from mgf.vm.core.configurator import display
from mgf.vm.core.exceptions import SpecValidationError


def _dom_vnc(port: str = "-1", listen: str = "127.0.0.1") -> ET.Element:
    return ET.fromstring(
        f"<domain><name>web</name><uuid>u</uuid>"
        f"<devices><graphics type='vnc' listen='{listen}' port='{port}'/></devices>"
        f"</domain>"
    )


def _dom_no_display() -> ET.Element:
    return ET.fromstring("<domain><name>web</name><uuid>u</uuid><devices/></domain>")


class TestPlan:
    def test_vnc_to_spice_requires_shutdown(self) -> None:
        change = display.plan(_dom_vnc(), display_type="spice")
        assert "display vnc -> spice" in change.summary
        assert change.requires_shutdown is True
        assert 'type="spice"' in change.new_xml or "type='spice'" in change.new_xml

    def test_vnc_to_none_removes_graphics(self) -> None:
        change = display.plan(_dom_vnc(), display_type="none")
        assert "display vnc -> none" in change.summary
        assert "<graphics" not in change.new_xml

    def test_listen_change(self) -> None:
        change = display.plan(_dom_vnc(), listen="0.0.0.0")
        assert "listen -> 0.0.0.0" in change.summary
        assert "0.0.0.0" in change.new_xml

    def test_port_change(self) -> None:
        change = display.plan(_dom_vnc(), port=5901)
        assert "port -> 5901" in change.summary

    def test_noop(self) -> None:
        change = display.plan(_dom_vnc(), display_type="vnc")
        assert change.summary == "no change"
        assert change.requires_shutdown is False

    def test_enable_on_empty(self) -> None:
        change = display.plan(_dom_no_display(), display_type="vnc")
        assert "display none -> vnc" in change.summary
        assert "<graphics" in change.new_xml

    def test_none_on_empty_is_noop(self) -> None:
        change = display.plan(_dom_no_display(), display_type="none")
        assert change.summary == "no change"

    def test_invalid_type(self) -> None:
        with pytest.raises(SpecValidationError):
            display.plan(_dom_vnc(), display_type="ascii")
