"""``configurator/firmware`` — BIOS / UEFI firmware selection (pure planner).

Firmware is baked into QEMU's command line at process start — switching
between BIOS and UEFI on a running VM is never safe, so every change this
module produces flags ``requires_shutdown=True``.

The UEFI path points at the OVMF loader present on Ubuntu 24.04+. The
planner only records the intent in the XML; verifying that the firmware
package is installed is a host-check workflow owned by the adapter.

**Pure core.** :func:`plan` accepts an *already-parsed*
:class:`xml.etree.ElementTree.Element`; the ``apply()`` half stays in the
adapter (``mgf-vm``).
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from mgf.vm.core.configurator.types import ConfigChange
from mgf.vm.core.configurator.xml_helpers import ensure, remove, serialize_domain_xml
from mgf.vm.core.exceptions import SpecValidationError

if TYPE_CHECKING:
    import xml.etree.ElementTree as ET

SUBSYSTEM = "firmware"

_OVMF_CODE_PATH = "/usr/share/OVMF/OVMF_CODE.fd"


def plan(
    domain: ET.Element,
    *,
    firmware: str | None = None,
    secure_boot: bool | None = None,
) -> ConfigChange:
    """Produce a :class:`ConfigChange` for a firmware edit.

    ``domain`` is the parsed domain root element (injected by the
    adapter); it is mutated in place. ``firmware`` must be ``"bios"`` or
    ``"uefi"``. ``secure_boot`` is only meaningful for UEFI; for BIOS it
    is silently ignored.
    """
    if firmware is not None and firmware not in {"bios", "uefi"}:
        raise SpecValidationError([f"firmware must be 'bios' or 'uefi', got {firmware!r}"])

    old_xml = serialize_domain_xml(domain)
    os_el = ensure(domain, "os")

    diffs: list[str] = []

    current_loader = os_el.find("loader")
    is_uefi = current_loader is not None and "OVMF" in (current_loader.text or "")
    current_firmware = "uefi" if is_uefi else "bios"
    current_secure = current_loader.get("secure") == "yes" if current_loader is not None else False

    target_firmware = firmware or current_firmware
    target_secure = secure_boot if secure_boot is not None else current_secure

    if target_firmware != current_firmware:
        diffs.append(f"firmware {current_firmware} -> {target_firmware}")

    if target_firmware == "uefi":
        loader_el = ensure(domain, "os/loader")
        loader_el.text = _OVMF_CODE_PATH
        loader_el.set("readonly", "yes")
        loader_el.set("type", "pflash")
        if target_secure:
            loader_el.set("secure", "yes")
        else:
            loader_el.attrib.pop("secure", None)
        if target_secure != current_secure:
            state = "on" if target_secure else "off"
            diffs.append(f"secure_boot -> {state}")
    else:
        # BIOS -> drop any UEFI loader element entirely.
        if current_loader is not None:
            remove(domain, "os/loader")

    summary = ", ".join(diffs) or "no change"
    return ConfigChange(
        subsystem=SUBSYSTEM,
        summary=summary,
        old_xml=old_xml,
        new_xml=serialize_domain_xml(domain),
        requires_shutdown=bool(diffs),
    )


__all__ = ["SUBSYSTEM", "plan"]
