"""
Skip Service - Determines if test cases should be skipped based on tags.
Handles test case filtering logic for skip rules.
"""

import re
from typing import Dict, Any


class SkipService:
    """
    Service responsible for determining if test cases should be skipped.
    Only #skip tag is allowed (case insensitive).
    """

    # Only #skip tag is allowed (case insensitive)
    SKIP_TAGS = {"#skip"}
    
    # Only match tags starting with #, not @
    _TOKEN_RE = re.compile(r"#([A-Za-z0-9_-]+)")

    def __init__(self):
        """Initialize the skip service."""
        pass

    def is_test_case_skipped(self, test_case: Dict[str, Any]) -> bool:
        """
        Return True if a test case is tagged to be skipped.

        A test can be tagged in any of these places:
        - title: e.g., "My test #skip"
        - tags field: list[str] or comma-separated string
        - metadata field: may contain {"tags": [...]} or any string with tokens
        - description field
        """
        try:
            # Title scan
            title = str(test_case.get("title", ""))
            if self._contains_skip_token(title):
                return True

            # Dedicated tags field (list or string)
            tags = test_case.get("tags")
            if isinstance(tags, list):
                if any(self._contains_skip_token(str(t)) for t in tags):
                    return True
            elif isinstance(tags, str):
                if self._contains_skip_token(tags):
                    return True

            # Metadata container
            metadata = test_case.get("metadata")
            if isinstance(metadata, dict):
                m_tags = metadata.get("tags")
                if isinstance(m_tags, list) and any(self._contains_skip_token(str(t)) for t in m_tags):
                    return True
                if isinstance(m_tags, str) and self._contains_skip_token(m_tags):
                    return True
                # Fallback string scan in metadata values
                if any(self._contains_skip_token(str(v)) for v in metadata.values()):
                    return True
            elif isinstance(metadata, str):
                if self._contains_skip_token(metadata):
                    return True

            # Description scan
            description = str(test_case.get("description", ""))
            if self._contains_skip_token(description):
                return True

            return False
        except Exception:
            # If any error occurs in parsing, default to not skipped
            return False

    def _contains_skip_token(self, text: str) -> bool:
        """Check if text contains a skip token (#skip)."""
        if not text:
            return False
        try:
            # Only find tokens starting with # (reject @ tokens)
            # Extract tag names without the # prefix
            tag_names = set(self._TOKEN_RE.findall(text))
            # Check if any tag name matches "skip" (case insensitive)
            return "skip" in {name.lower() for name in tag_names}
        except Exception:
            return False


# Maintain backward compatibility with function-based API
_skip_service_instance = SkipService()


def is_test_case_skipped(test_case: Dict[str, Any]) -> bool:
    """
    Backward compatibility function.
    Return True if a test case is tagged to be skipped.
    """
    return _skip_service_instance.is_test_case_skipped(test_case)


__all__ = ["SkipService", "is_test_case_skipped"]
