"""
Concrete implementations of context detection interfaces.
"""

import inspect
import re
from pathlib import Path
from typing import Any

from .context_interfaces import FileSystemInspector, FrameInspector, PathAnalyzer, PatternMatcher


class DefaultFrameInspector(FrameInspector):
    """Default implementation using Python's inspect module."""

    def get_current_frame(self) -> Any | None:
        """Get the current execution frame."""
        return inspect.currentframe()

    def get_frame_info(self, frame: Any) -> tuple[str, str, int]:
        """Extract filename, function name, and line number from frame."""
        return (frame.f_code.co_filename, frame.f_code.co_name, frame.f_lineno)

    def get_frame_locals(self, frame: Any) -> dict[str, Any]:
        """Get local variables from frame."""
        return dict(frame.f_locals)  # Ensure we return a dict, not Any

    def get_parent_frame(self, frame: Any) -> Any | None:
        """Get the parent frame."""
        return frame.f_back


class DefaultFileSystemInspector(FileSystemInspector):
    """Default implementation using pathlib."""

    def get_current_directory(self) -> Path:
        """Get the current working directory."""
        return Path.cwd()

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

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


class DefaultPathAnalyzer(PathAnalyzer):
    """Default implementation for path analysis."""

    def relative_to(self, path: Path, base: Path) -> Path | None:
        """Get relative path from base, returns None if not relative."""
        try:
            return path.relative_to(base)
        except (ValueError, OSError):
            return None

    def get_parts(self, path: Path) -> tuple[str, ...]:
        """Get path components."""
        return path.parts

    def get_stem(self, path: Path) -> str:
        """Get filename without extension."""
        return path.stem


class DefaultPatternMatcher(PatternMatcher):
    """Default implementation using regex."""

    def match_file_pattern(self, filename: str, pattern: str) -> bool:
        """Check if filename matches a regex pattern."""
        return bool(re.search(pattern, filename))

    def match_function_pattern(self, function_name: str, pattern: str) -> bool:
        """Check if function name matches a regex pattern."""
        return bool(re.match(pattern, function_name))

    def match_class_pattern(self, class_name: str, pattern: str) -> bool:
        """Check if class name matches a regex pattern."""
        return bool(re.match(pattern, class_name))
