"""Tests for the inject-Element disk-target pairing helpers
(mgf.vm.core.operations.xml_rewrite.pair_disk_targets / default_disk_target).

These pass an already-parsed Element (as the adapter would, after
defusedxml parsing). The original ``_parse_disk_targets`` in
``mgf.vm.operations.backup`` began with a string parse + ParseError
fallback — both adapter concerns. Here we test only the pure positional
pairing over an injected tree.
"""

from __future__ import annotations

import xml.etree.ElementTree as ET
from pathlib import Path

from mgf.vm.core.operations.xml_rewrite import default_disk_target, pair_disk_targets


def _domain_with_disks(*target_devs: str | None) -> ET.Element:
    root = ET.Element("domain")
    devices = ET.SubElement(root, "devices")
    for dev in target_devs:
        disk = ET.SubElement(devices, "disk")
        if dev is not None:
            t = ET.SubElement(disk, "target")
            t.set("dev", dev)
    return root


# --- default_disk_target -------------------------------------------------


def test_default_disk_target_sequence() -> None:
    assert default_disk_target(0) == "vda"
    assert default_disk_target(1) == "vdb"
    assert default_disk_target(25) == "vdz"


# --- pair_disk_targets ---------------------------------------------------


def test_pair_uses_explicit_target_dev() -> None:
    root = _domain_with_disks("sda", "sdb")
    paths = [Path("/d/0.qcow2"), Path("/d/1.qcow2")]
    assert pair_disk_targets(root, paths) == [
        ("sda", Path("/d/0.qcow2")),
        ("sdb", Path("/d/1.qcow2")),
    ]


def test_pair_falls_back_when_disk_has_no_target_element() -> None:
    root = _domain_with_disks(None)  # <disk> with no <target>
    paired = pair_disk_targets(root, [Path("/d/0.qcow2")])
    assert paired == [("vda", Path("/d/0.qcow2"))]


def test_pair_falls_back_when_target_has_no_dev_attr() -> None:
    root = ET.Element("domain")
    devices = ET.SubElement(root, "devices")
    disk = ET.SubElement(devices, "disk")
    ET.SubElement(disk, "target")  # <target> without dev=
    paired = pair_disk_targets(root, [Path("/d/0.qcow2")])
    assert paired == [("vda", Path("/d/0.qcow2"))]


def test_pair_falls_back_when_more_paths_than_disk_elements() -> None:
    root = _domain_with_disks("sda")  # one disk element
    paired = pair_disk_targets(root, [Path("/a"), Path("/b"), Path("/c")])
    assert paired == [
        ("sda", Path("/a")),
        ("vdb", Path("/b")),  # synthetic, index 1
        ("vdc", Path("/c")),  # synthetic, index 2
    ]


def test_pair_preserves_str_path_type() -> None:
    root = _domain_with_disks("sda")
    paired = pair_disk_targets(root, ["/raw/string/path"])
    assert paired == [("sda", "/raw/string/path")]
    assert isinstance(paired[0][1], str)


def test_pair_empty_paths_returns_empty() -> None:
    root = _domain_with_disks("sda", "sdb")
    assert pair_disk_targets(root, []) == []


def test_pair_no_disk_elements_all_synthetic() -> None:
    root = ET.Element("domain")
    ET.SubElement(root, "devices")  # no <disk> children
    paired = pair_disk_targets(root, [Path("/a"), Path("/b")])
    assert paired == [("vda", Path("/a")), ("vdb", Path("/b"))]
