# Copyright Visual Collaboration Technologies Inc. All Rights Reserved.
# See LICENSE for details.
"""Tests for TemplateRegistry."""

import re

import pytest

import vcti.template
from vcti.template import TemplateNotFoundError, TemplateRegistry


class TestVersion:
    def test_version_exists(self):
        assert hasattr(vcti.template, "__version__")

    def test_version_is_valid_semver(self):
        assert re.match(r"^\d+\.\d+\.\d+", vcti.template.__version__)


class TestRegister:
    def test_register_and_get(self):
        reg = TemplateRegistry()
        reg.register("hello", "Hello, {{ name }}!")
        assert reg.get("hello") == "Hello, {{ name }}!"

    def test_register_duplicate_raises(self):
        reg = TemplateRegistry()
        reg.register("hello", "first")
        with pytest.raises(KeyError, match="already registered"):
            reg.register("hello", "second")

    def test_register_duplicate_with_replace(self):
        reg = TemplateRegistry()
        reg.register("hello", "first")
        reg.register("hello", "second", replace=True)
        assert reg.get("hello") == "second"

    @pytest.mark.parametrize("bad_name", ["", "   ", "\t", "\n"])
    def test_register_empty_name_raises(self, bad_name):
        reg = TemplateRegistry()
        with pytest.raises(ValueError, match="non-empty string"):
            reg.register(bad_name, "template")

    @pytest.mark.parametrize("bad_name", [123, None, True, []])
    def test_register_non_string_name_raises(self, bad_name):
        reg = TemplateRegistry()
        with pytest.raises(ValueError, match="non-empty string"):
            reg.register(bad_name, "template")

    def test_register_empty_template_body(self):
        reg = TemplateRegistry()
        reg.register("empty", "")
        assert reg.get("empty") == ""


class TestGet:
    def test_get_missing_raises(self):
        reg = TemplateRegistry()
        with pytest.raises(TemplateNotFoundError, match="not found"):
            reg.get("missing")

    def test_get_missing_is_lookup_error(self):
        """TemplateNotFoundError inherits LookupError for compatibility."""
        reg = TemplateRegistry()
        with pytest.raises(LookupError):
            reg.get("missing")


class TestHas:
    def test_has_existing(self):
        reg = TemplateRegistry()
        reg.register("hello", "template")
        assert reg.has("hello") is True

    def test_has_missing(self):
        reg = TemplateRegistry()
        assert reg.has("missing") is False


class TestContains:
    def test_contains(self):
        reg = TemplateRegistry()
        reg.register("hello", "template")
        assert "hello" in reg
        assert "missing" not in reg


class TestRemove:
    def test_remove_existing(self):
        reg = TemplateRegistry()
        reg.register("hello", "template")
        reg.remove("hello")
        assert not reg.has("hello")

    def test_remove_missing_raises(self):
        reg = TemplateRegistry()
        with pytest.raises(TemplateNotFoundError, match="not found"):
            reg.remove("missing")


class TestNames:
    def test_names(self):
        reg = TemplateRegistry()
        reg.register("a", "template a")
        reg.register("b", "template b")
        assert reg.names() == ["a", "b"]

    def test_names_empty(self):
        reg = TemplateRegistry()
        assert reg.names() == []


class TestTemplatesProperty:
    def test_templates_immutable(self):
        reg = TemplateRegistry()
        reg.register("hello", "template")
        with pytest.raises(TypeError):
            reg.templates["hello"] = "modified"

    def test_templates_reflects_state(self):
        reg = TemplateRegistry()
        reg.register("hello", "template")
        assert dict(reg.templates) == {"hello": "template"}


class TestLen:
    def test_len(self):
        reg = TemplateRegistry()
        assert len(reg) == 0
        reg.register("a", "template")
        assert len(reg) == 1


class TestRepr:
    def test_repr(self):
        reg = TemplateRegistry()
        reg.register("hello", "template")
        assert "TemplateRegistry" in repr(reg)
        assert "'hello'" in repr(reg)
