"""RegexCheck: Validate output against a regex pattern."""

from __future__ import annotations

import re
from typing import Any

from ai_qa.checks.registry import 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 ContextValidationError


@register("regex")
class RegexCheck(BaseCheck):
    r"""Validate output matches a regex pattern.

    Requires:
        - ctx.output: string to match
        - pattern: regex pattern string (passed via config)

    Example:
        check = RegexCheck(pattern=r"^[a-z]+@[a-z]+\.[a-z]+$")
    """

    requires_llm = False
    version = "1.0.0"
    description = "Validate output matches a regex pattern"

    def __init__(
        self,
        threshold: float = 0.5,
        pattern: str | None = None,
        flags: int = 0,
        **kwargs: Any,
    ) -> None:
        r"""Initialize RegexCheck.

        Args:
            threshold: Score threshold (0.0-1.0).
            pattern: Regex pattern string to match against.
            flags: Regex flags (e.g., re.IGNORECASE, re.MULTILINE).
            **kwargs: Additional config kwargs.

        Raises:
            ValueError: If pattern is missing or invalid.
        """
        super().__init__(threshold=threshold, **kwargs)
        if pattern is None:
            raise ValueError(
                "RegexCheck requires a 'pattern' parameter.\n"
                r"Example: RegexCheck(pattern=r'^[a-z]+@[a-z]+\.[a-z]+$')"
            )
        try:
            self.pattern_obj = re.compile(pattern, flags)
            self.pattern = pattern
            self.flags = flags
        except re.error as e:
            msg = f"Invalid regex pattern: {str(e)}"
            raise ValueError(msg)

    def validate_context(self, ctx: Context) -> None:
        """Validate that output is a string.

        Args:
            ctx: Context to validate.

        Raises:
            ContextValidationError: If output is not a string.
        """
        if ctx.output is None:
            raise ContextValidationError(
                "RegexCheck requires ctx.output to be set.\n"
                "Example: Context(output='user@example.com')"
            )
        if not isinstance(ctx.output, str):
            raise ContextValidationError(
                f"RegexCheck requires ctx.output to be a string, got {type(ctx.output).__name__}"
            )

    def evaluate(self, ctx: Context) -> CheckResult:
        """Evaluate output against regex pattern.

        Args:
            ctx: Context with output to validate.

        Returns:
            CheckResult with pass/fail and evidence.
        """
        self.validate_context(ctx)
        assert isinstance(ctx.output, str)

        if self.pattern_obj.search(ctx.output):
            return CheckResult(
                name=self.name,
                passed=True,
                score=1.0,
                threshold=self.threshold,
                evidence=f"Output matches pattern: {self.pattern}",
                check_version=self.version,
            )
        else:
            return CheckResult(
                name=self.name,
                passed=False,
                score=0.0,
                threshold=self.threshold,
                evidence=f"Output does not match pattern: {self.pattern}",
                check_version=self.version,
            )
