"""Tests for the VM naming rule leaf (mgf.vm.core.names)."""

from __future__ import annotations

import pytest

from mgf.vm.core.names import VM_NAME_REGEX, VM_NAME_RULE, is_valid_vm_name


@pytest.mark.parametrize(
    "name",
    [
        "a",
        "A",
        "0",
        "vm1",
        "web-server-01",
        "host.example.com",
        "under_score",
        "a" * 63,  # max length
        "9lives",
    ],
)
def test_valid_names(name: str) -> None:
    assert is_valid_vm_name(name) is True
    assert VM_NAME_REGEX.match(name) is not None


@pytest.mark.parametrize(
    "name",
    [
        "",  # empty
        "-leading-hyphen",
        ".leading-dot",
        "_leading-underscore",
        "has space",
        "has/slash",
        "has:colon",
        "tab\there",
        "a" * 64,  # one over the limit
        "naughty\nname",
    ],
)
def test_invalid_names(name: str) -> None:
    assert is_valid_vm_name(name) is False


@pytest.mark.parametrize("value", [None, 123, b"bytes-not-str", ["list"]])
def test_non_string_is_invalid_and_does_not_raise(value: object) -> None:
    # Must return False, never raise — callers build the typed error themselves.
    assert is_valid_vm_name(value) is False  # type: ignore[arg-type]


def test_rule_text_is_usable_in_error_message() -> None:
    assert "1-63" in VM_NAME_RULE
    msg = f"name 'bad name' is invalid: {VM_NAME_RULE}"
    assert VM_NAME_RULE in msg


def test_max_length_boundary() -> None:
    assert is_valid_vm_name("a" * 63) is True
    assert is_valid_vm_name("a" * 64) is False
