"""Field-based log filtering."""

import re
from collections.abc import Callable
from re import Pattern
from typing import Any

from ..core.backend import LogRecord


class FieldFilter:
    """Filter logs based on field values."""

    def __init__(
        self,
        include_fields: dict[str, Any] | None = None,
        exclude_fields: dict[str, Any] | None = None,
        required_fields: set[str] | None = None,
        forbidden_fields: set[str] | None = None,
        field_validators: dict[str, Callable[[Any], bool]] | None = None,
        regex_patterns: dict[str, Pattern[str]] | None = None
    ) -> None:
        """Initialize field filter.
        
        Args:
            include_fields: Fields that must match these values to be included
            exclude_fields: Fields that match these values will be excluded
            required_fields: Set of field names that must be present
            forbidden_fields: Set of field names that must not be present
            field_validators: Custom validation functions for specific fields
            regex_patterns: Regex patterns that field values must match
        """
        self.include_fields = include_fields or {}
        self.exclude_fields = exclude_fields or {}
        self.required_fields = required_fields or set()
        self.forbidden_fields = forbidden_fields or set()
        self.field_validators = field_validators or {}
        self.regex_patterns = regex_patterns or {}

    def should_log(self, record: LogRecord) -> bool:
        """Check if record should be logged based on field criteria.
        
        Args:
            record: The log record to check
            
        Returns:
            True if record should be logged, False otherwise
        """
        # Check required fields
        record_fields = set(record.extra.keys())
        if self.required_fields and not self.required_fields.issubset(record_fields):
            return False

        # Check forbidden fields
        if self.forbidden_fields and self.forbidden_fields.intersection(record_fields):
            return False

        # Check include fields
        for field_name, expected_value in self.include_fields.items():
            if field_name not in record.extra:
                return False
            if record.extra[field_name] != expected_value:
                return False

        # Check exclude fields
        for field_name, excluded_value in self.exclude_fields.items():
            if field_name in record.extra:
                if record.extra[field_name] == excluded_value:
                    return False

        # Check custom validators
        for field_name, validator in self.field_validators.items():
            if field_name in record.extra:
                if not validator(record.extra[field_name]):
                    return False

        # Check regex patterns
        for field_name, pattern in self.regex_patterns.items():
            if field_name in record.extra:
                field_value = str(record.extra[field_name])
                if not pattern.match(field_value):
                    return False

        return True

    @classmethod
    def create_regex_filter(cls, field_patterns: dict[str, str]) -> "FieldFilter":
        """Create a field filter with regex patterns.
        
        Args:
            field_patterns: Dictionary mapping field names to regex pattern strings
            
        Returns:
            FieldFilter instance with compiled regex patterns
        """
        compiled_patterns = {
            field_name: re.compile(pattern)
            for field_name, pattern in field_patterns.items()
        }
        return cls(regex_patterns=compiled_patterns)
