"""Tests for constants defined in the MCP server module.

All assertions verify exact values copied from ``mcp/vm_blackbox.py`` so
that any accidental divergence between the canonical source and the
installable package is caught immediately.

Constants live in _helpers after modularization; tests import from there.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest

if TYPE_CHECKING:
    import types


@pytest.fixture
def helpers_module() -> types.ModuleType:
    """Provide the _helpers module (canonical source for constants)."""
    import mcp_vm_blackbox._helpers as h

    return h


class TestKeyMap:
    """Tests for ``KEY_MAP``."""

    def test_key_map_has_required_keys(self, helpers_module: types.ModuleType) -> None:
        """KEY_MAP must contain all five supported key names.

        Args:
            helpers_module: The _helpers module.
        """
        key_map: dict[str, str] = helpers_module.KEY_MAP
        for key in ("enter", "tab", "escape", "space", "backspace"):
            assert key in key_map, f"Missing key: {key!r}"

    def test_key_map_values_are_strings(self, helpers_module: types.ModuleType) -> None:
        """Every value in KEY_MAP must be a non-empty string.

        Args:
            helpers_module: The _helpers module.
        """
        for k, v in helpers_module.KEY_MAP.items():
            assert isinstance(v, str), f"KEY_MAP[{k!r}] is not a str"
            assert v, f"KEY_MAP[{k!r}] is an empty string"

    def test_enter_maps_to_return(self, helpers_module: types.ModuleType) -> None:
        """'enter' must map to the X11 symbol 'Return'.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.KEY_MAP["enter"] == "Return"

    def test_backspace_maps_to_backspace_symbol(self, helpers_module: types.ModuleType) -> None:
        """'backspace' must map to the X11 symbol 'BackSpace'.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.KEY_MAP["backspace"] == "BackSpace"

    def test_tab_maps_to_tab_symbol(self, helpers_module: types.ModuleType) -> None:
        """'tab' must map to the X11 symbol 'Tab'.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.KEY_MAP["tab"] == "Tab"

    def test_escape_maps_to_escape_symbol(self, helpers_module: types.ModuleType) -> None:
        """'escape' must map to the X11 symbol 'Escape'.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.KEY_MAP["escape"] == "Escape"

    def test_space_maps_to_space_symbol(self, helpers_module: types.ModuleType) -> None:
        """'space' must map to the X11 symbol 'space'.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.KEY_MAP["space"] == "space"


class TestBuildScripts:
    """Tests for ``BUILD_SCRIPTS``."""

    def test_build_scripts_is_dict(self, helpers_module: types.ModuleType) -> None:
        """BUILD_SCRIPTS must be a dict (populated via config, not hardcoded).

        Args:
            helpers_module: The _helpers module.
        """
        assert isinstance(helpers_module.BUILD_SCRIPTS, dict)

    def test_build_scripts_empty_by_default(self, helpers_module: types.ModuleType) -> None:
        """BUILD_SCRIPTS must be empty by default; populated via
        MCP_VM_BLACKBOX_BUILD_SCRIPTS env var or project config.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.BUILD_SCRIPTS == {}

    def test_build_scripts_values_are_strings(self, helpers_module: types.ModuleType) -> None:
        """Every BUILD_SCRIPTS value must be a non-empty string path.

        Args:
            helpers_module: The _helpers module.
        """
        for alias, path in helpers_module.BUILD_SCRIPTS.items():
            assert isinstance(path, str), f"BUILD_SCRIPTS[{alias!r}] is not a str"
            assert path, f"BUILD_SCRIPTS[{alias!r}] is empty"


class TestVersionRequirements:
    """Tests for ``VERSION_REQUIREMENTS``."""

    def test_version_requirements_has_vboxmanage(self, helpers_module: types.ModuleType) -> None:
        """VERSION_REQUIREMENTS must specify a minimum VBoxManage version.

        Args:
            helpers_module: The _helpers module.
        """
        assert "VBoxManage" in helpers_module.VERSION_REQUIREMENTS

    def test_version_requirements_has_vagrant(self, helpers_module: types.ModuleType) -> None:
        """VERSION_REQUIREMENTS must specify a minimum vagrant version.

        Args:
            helpers_module: The _helpers module.
        """
        assert "vagrant" in helpers_module.VERSION_REQUIREMENTS

    def test_version_requirements_has_packer(self, helpers_module: types.ModuleType) -> None:
        """VERSION_REQUIREMENTS must specify a minimum packer version.

        Args:
            helpers_module: The _helpers module.
        """
        assert "packer" in helpers_module.VERSION_REQUIREMENTS

    def test_version_requirements_values_are_strings(self, helpers_module: types.ModuleType) -> None:
        """Every VERSION_REQUIREMENTS value must be a non-empty version string.

        Args:
            helpers_module: The _helpers module.
        """
        for tool, ver in helpers_module.VERSION_REQUIREMENTS.items():
            assert isinstance(ver, str), f"VERSION_REQUIREMENTS[{tool!r}] is not a str"
            assert ver, f"VERSION_REQUIREMENTS[{tool!r}] is empty"

    def test_vboxmanage_minimum_version(self, helpers_module: types.ModuleType) -> None:
        """VBoxManage minimum version must be 7.0.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.VERSION_REQUIREMENTS["VBoxManage"] == "7.0"

    def test_vagrant_minimum_version(self, helpers_module: types.ModuleType) -> None:
        """vagrant minimum version must be 2.3.

        Args:
            helpers_module: The _helpers module.
        """
        assert helpers_module.VERSION_REQUIREMENTS["vagrant"] == "2.3"


class TestBuildTerminalMarkers:
    """Tests for ``BUILD_TERMINAL_MARKERS``."""

    def test_build_terminal_markers_is_tuple(self, helpers_module: types.ModuleType) -> None:
        """BUILD_TERMINAL_MARKERS must be a tuple (immutable, hashable).

        Args:
            helpers_module: The _helpers module.
        """
        assert isinstance(helpers_module.BUILD_TERMINAL_MARKERS, tuple)

    def test_build_terminal_markers_contains_success(self, helpers_module: types.ModuleType) -> None:
        """BUILD_TERMINAL_MARKERS must contain the success sentinel.

        Args:
            helpers_module: The _helpers module.
        """
        assert "Build successful" in helpers_module.BUILD_TERMINAL_MARKERS

    def test_build_terminal_markers_contains_failed(self, helpers_module: types.ModuleType) -> None:
        """BUILD_TERMINAL_MARKERS must contain the failure sentinel.

        Args:
            helpers_module: The _helpers module.
        """
        assert "FAILED" in helpers_module.BUILD_TERMINAL_MARKERS

    def test_build_terminal_markers_contains_error(self, helpers_module: types.ModuleType) -> None:
        """BUILD_TERMINAL_MARKERS must contain the 'Error:' sentinel.

        Args:
            helpers_module: The _helpers module.
        """
        assert "Error:" in helpers_module.BUILD_TERMINAL_MARKERS

    def test_build_terminal_markers_contains_exited(self, helpers_module: types.ModuleType) -> None:
        """BUILD_TERMINAL_MARKERS must contain the 'exited with' sentinel.

        Args:
            helpers_module: The _helpers module.
        """
        assert "exited with" in helpers_module.BUILD_TERMINAL_MARKERS

    def test_build_terminal_markers_non_empty(self, helpers_module: types.ModuleType) -> None:
        """BUILD_TERMINAL_MARKERS must be non-empty.

        Args:
            helpers_module: The _helpers module.
        """
        assert len(helpers_module.BUILD_TERMINAL_MARKERS) > 0
