"""Tests for check registry and @register decorator."""

from __future__ import annotations

import pytest

from ai_qa.checks.registry import CheckRegistry, register
from ai_qa.core.check import BaseCheck
from ai_qa.core.context import Context
from ai_qa.core.result import CheckResult
from ai_qa.exceptions import CheckNotFoundError


class SimpleCheck(BaseCheck):
    """Simple test check."""

    def evaluate(self, ctx: Context) -> CheckResult:
        """Dummy evaluate."""
        return CheckResult(
            name=self.name,
            passed=True,
            score=1.0,
            threshold=self.threshold,
            evidence="Test",
            check_version=self.version,
        )


def test_register_decorator():
    """Test that @register decorator registers a check."""

    @register("test_check_1")
    class TestCheck1(SimpleCheck):
        """Test check."""

        pass

    # Check should now be registered
    assert "test_check_1" in CheckRegistry.list()
    assert CheckRegistry.get("test_check_1") is TestCheck1


def test_registry_get_existing():
    """Test retrieving an existing check."""
    # Schema check should be registered (auto-imported)
    assert CheckRegistry.get("schema") is not None


def test_registry_get_not_found():
    """Test retrieving non-existent check raises error."""
    with pytest.raises(CheckNotFoundError) as exc_info:
        CheckRegistry.get("nonexistent_check")
    assert "nonexistent_check" not in CheckRegistry.list()
    assert "Available checks:" in str(exc_info.value)


def test_registry_list():
    """Test listing all registered checks."""
    checks = CheckRegistry.list()
    assert isinstance(checks, list)
    assert "schema" in checks
    assert "regex" in checks
    assert "json_format" in checks
    assert "length" in checks
    # List should be sorted
    assert checks == sorted(checks)


def test_registry_instantiate():
    """Test creating check instance via registry."""
    check = CheckRegistry.instantiate("schema", schema={"type": "object"})
    assert check is not None
    assert check.name == "schema"


def test_registry_instantiate_not_found():
    """Test instantiating non-existent check raises error."""
    with pytest.raises(CheckNotFoundError):
        CheckRegistry.instantiate("nonexistent")


def test_registry_instantiate_with_kwargs():
    """Test instantiating check with custom threshold."""
    check = CheckRegistry.instantiate(
        "length", min_length=5, max_length=10, threshold=0.8
    )
    assert check.threshold == 0.8
    assert check.min_length == 5
    assert check.max_length == 10


def test_register_sets_name():
    """Test that @register sets the check's name attribute."""

    @register("my_test_check")
    class MyTestCheck(SimpleCheck):
        """Test check."""

        pass

    check = MyTestCheck()
    assert check.name == "my_test_check"


def test_multiple_register_overwrite():
    """Test that registering same name overwrites previous registration."""

    @register("overwrite_test")
    class FirstCheck(SimpleCheck):
        """First check."""

        pass

    @register("overwrite_test")
    class SecondCheck(SimpleCheck):
        """Second check."""

        pass

    # Should be the second one
    assert CheckRegistry.get("overwrite_test") is SecondCheck
