"""
Abstract interfaces for context detection to improve testability.
"""

from abc import ABC, abstractmethod
from pathlib import Path
from typing import Any


class FrameInspector(ABC):
    """Abstract interface for frame inspection operations."""

    @abstractmethod
    def get_current_frame(self) -> Any | None:
        """Get the current execution frame."""
        pass

    @abstractmethod
    def get_frame_info(self, frame: Any) -> tuple[str, str, int]:
        """Extract filename, function name, and line number from frame."""
        pass

    @abstractmethod
    def get_frame_locals(self, frame: Any) -> dict[str, Any]:
        """Get local variables from frame."""
        pass

    @abstractmethod
    def get_parent_frame(self, frame: Any) -> Any | None:
        """Get the parent frame."""
        pass


class FileSystemInspector(ABC):
    """Abstract interface for file system operations."""

    @abstractmethod
    def get_current_directory(self) -> Path:
        """Get the current working directory."""
        pass

    @abstractmethod
    def exists(self, path: Path) -> bool:
        """Check if a path exists."""
        pass

    @abstractmethod
    def get_parents(self, path: Path) -> list[Path]:
        """Get parent directories of a path."""
        pass


class PathAnalyzer(ABC):
    """Abstract interface for path analysis operations."""

    @abstractmethod
    def relative_to(self, path: Path, base: Path) -> Path | None:
        """Get relative path from base, returns None if not relative."""
        pass

    @abstractmethod
    def get_parts(self, path: Path) -> tuple[str, ...]:
        """Get path components."""
        pass

    @abstractmethod
    def get_stem(self, path: Path) -> str:
        """Get filename without extension."""
        pass


class PatternMatcher(ABC):
    """Abstract interface for pattern matching operations."""

    @abstractmethod
    def match_file_pattern(self, filename: str, pattern: str) -> bool:
        """Check if filename matches a regex pattern."""
        pass

    @abstractmethod
    def match_function_pattern(self, function_name: str, pattern: str) -> bool:
        """Check if function name matches a regex pattern."""
        pass

    @abstractmethod
    def match_class_pattern(self, class_name: str, pattern: str) -> bool:
        """Check if class name matches a regex pattern."""
        pass
