from pve_vm_setup.domain import (
    build_create_payload,
    select_latest_nixos_iso,
    select_preferred_iso,
    validate_all_steps,
)
from pve_vm_setup.models.workflow import VmConfig
from pve_vm_setup.settings import AppSettings


def test_select_latest_nixos_iso_prefers_latest_year_month() -> None:
    choice = select_latest_nixos_iso(
        [
            "cephfs:iso/nixos-minimal-24.11.1234abcd-x86_64-linux.iso",
            "cephfs:iso/nixos-minimal-25.05.ffffeeee-x86_64-linux.iso",
            "cephfs:iso/debian-12.iso",
        ]
    )

    assert choice == "cephfs:iso/nixos-minimal-25.05.ffffeeee-x86_64-linux.iso"


def test_select_preferred_iso_uses_glob_selector_when_configured() -> None:
    choice = select_preferred_iso(
        [
            "cephfs:iso/debian-12.iso",
            "cephfs:iso/nixos-minimal-24.11.1234abcd-x86_64-linux.iso",
            "cephfs:iso/ubuntu-24.04.iso",
        ],
        "*ubuntu*",
    )

    assert choice == "cephfs:iso/ubuntu-24.04.iso"


def test_select_preferred_iso_uses_regex_selector_when_prefixed() -> None:
    choice = select_preferred_iso(
        [
            "cephfs:iso/debian-12.iso",
            "cephfs:iso/nixos-minimal-24.11.1234abcd-x86_64-linux.iso",
            "cephfs:iso/nixos-graphical-25.05.iso",
        ],
        r"regex:nixos-graphical-\d{2}\.\d{2}\.iso$",
    )

    assert choice == "cephfs:iso/nixos-graphical-25.05.iso"


def test_build_create_payload_applies_safety_name_tag_and_key_settings() -> None:
    settings = AppSettings.from_env(
        {
            "PROXMOX_PREVENT_CREATE": "false",
            "PROXMOX_ENABLE_TEST_MODE": "true",
            "PROXMOX_TEST_NODE": "fake-node-01",
            "PROXMOX_TEST_POOL": "lab",
        },
        load_dotenv_file=False,
    )
    config = VmConfig()
    config.general.node = "fake-node-01"
    config.general.vmid = 123
    config.general.name = "demo"
    config.general.tags = ["linux"]
    config.os.storage = "cephfs"
    config.os.iso = "cephfs:iso/nixos-minimal-25.05.ffffeeee-x86_64-linux.iso"

    payload = build_create_payload(config, settings)

    assert payload["name"] == "codex-e2e-demo"
    assert payload["tags"] == "codex-e2e;linux"
    assert payload["bios"] == "ovmf"
    assert payload["scsihw"] == "virtio-scsi-single"
    assert payload["allow-ksm"] == 1
    assert payload["net0"] == "model=virtio,bridge=vmbr9,firewall=1,link_down=0"
    assert payload["scsi0"] == (
        "ceph-pool:32,format=raw,cache=none,discard=ignore,"
        "iothread=1,ssd=1,backup=1,replicate=1,aio=io_uring"
    )


def test_validate_all_steps_requires_live_create_opt_in() -> None:
    settings = AppSettings.from_env(
        {
            "PROXMOX_PREVENT_CREATE": "true",
        },
        load_dotenv_file=False,
    )
    config = VmConfig()
    config.general.node = "fake-node-01"
    config.general.vmid = 123
    config.general.name = "demo"
    config.os.storage = "cephfs"
    config.os.iso = "cephfs:iso/nixos-minimal-25.05.ffffeeee-x86_64-linux.iso"

    errors = validate_all_steps(config, settings, references=type("Refs", (), {})())

    assert "Set PROXMOX_PREVENT_CREATE=false to enable VM creation." in errors


def test_build_create_payload_leaves_name_and_tags_untouched_outside_test_mode() -> None:
    settings = AppSettings.from_env(
        {
            "PROXMOX_PREVENT_CREATE": "false",
        },
        load_dotenv_file=False,
    )
    config = VmConfig()
    config.general.node = "fake-node-01"
    config.general.vmid = 123
    config.general.name = "demo"
    config.general.tags = ["linux"]
    config.os.storage = "cephfs"
    config.os.iso = "cephfs:iso/nixos-minimal-25.05.ffffeeee-x86_64-linux.iso"

    payload = build_create_payload(config, settings)

    assert payload["name"] == "demo"
    assert payload["tags"] == "linux"


def test_build_create_payload_can_disable_allow_ksm() -> None:
    settings = AppSettings.from_env(
        {
            "PROXMOX_PREVENT_CREATE": "false",
        },
        load_dotenv_file=False,
    )
    config = VmConfig()
    config.general.node = "fake-node-01"
    config.general.vmid = 123
    config.general.name = "demo"
    config.os.storage = "cephfs"
    config.os.iso = "cephfs:iso/nixos-minimal-25.05.ffffeeee-x86_64-linux.iso"
    config.memory.allow_ksm = False

    payload = build_create_payload(config, settings)

    assert payload["allow-ksm"] == 0
