"""Network-related fix executors.

Pure: the only adapter coupling in the original was the
``QUARANTINE_NETWORK_NAME`` constant, now sourced from the pure
:mod:`mgf.vm.core.security.isolation.context`. Nothing here touches
``defusedxml`` / ``static_analyzer``.
"""

from __future__ import annotations

import xml.etree.ElementTree as ET
from typing import TYPE_CHECKING, Any

from mgf.vm.core.security.isolation.context import QUARANTINE_NETWORK_NAME
from mgf.vm.core.security.isolation.fixes._helpers import devices_element
from mgf.vm.core.security.isolation.types import isolation_fix

if TYPE_CHECKING:
    from mgf.vm.core.common.progress import ProgressReporter


__all__ = ["network_swap_to_quarantine"]


@isolation_fix("network.swap_to_quarantine")
def network_swap_to_quarantine(
    *,
    target: ET.ElementTree,
    reporter: ProgressReporter,
    dry_run: bool = False,
    **_kw: Any,
) -> None:
    """Rewrite every ``<interface type='network'>`` to point at the
    canonical quarantine network.

    Idempotent: an interface already attached to
    ``vmanager-quarantine`` is left alone.
    """
    devices = devices_element(target)
    if devices is None:
        reporter.report("network.swap_to_quarantine: no <devices> element")
        return

    swapped = 0
    skipped = 0
    for iface in devices.findall("interface"):
        if iface.get("type") != "network":
            continue
        source = iface.find("source")
        if source is None:
            source = ET.SubElement(iface, "source")
        current = source.get("network", "")
        if current == QUARANTINE_NETWORK_NAME:
            skipped += 1
            continue
        if dry_run:
            reporter.report(
                f"network.swap_to_quarantine: (dry-run) would swap "
                f"{current!r} → {QUARANTINE_NETWORK_NAME!r}",
            )
        else:
            source.set("network", QUARANTINE_NETWORK_NAME)
        swapped += 1

    if swapped == 0:
        reporter.report(
            f"network.swap_to_quarantine: already satisfied ({skipped} interface(s) "
            f"already on '{QUARANTINE_NETWORK_NAME}')"
            if skipped
            else "network.swap_to_quarantine: no <interface type='network'> elements",
        )
        return
    if not dry_run:
        reporter.report(
            f"network.swap_to_quarantine: rewrote {swapped} interface(s) "
            f"to '{QUARANTINE_NETWORK_NAME}'",
        )
