"""
Base strategy interfaces for DSS Claude Plugin.

This module defines the abstract base classes that all strategy implementations
must adhere to. These interfaces ensure consistent behavior across different
execution modes (LOCAL vs REMOTE) and allow the context to switch strategies
transparently.
"""

from abc import ABC, abstractmethod
from typing import List, Optional, Dict, Any


class BrowserStrategy(ABC):
    """
    Abstract base strategy for browser interactions.

    Provides methods for inspecting and interacting with a web page.
    Implementations will handle the underlying automation (e.g., Playwright
    for local, API calls for remote).
    """

    @abstractmethod
    async def get_console_logs(
        self,
        session_id: Optional[str] = None,
        limit: int = 100,
        level: Optional[str] = None
    ) -> List[Dict[str, Any]]:
        """
        Retrieve console logs from the browser session.

        Args:
            session_id: The active session identifier (optional for LOCAL mode).
            limit: Maximum number of logs to return.
            level: Filter by log level (e.g., "log", "warn", "error").

        Returns:
            List of log entries containing message, level, and timestamp.
        """
        pass

    @abstractmethod
    async def capture_screenshot(
        self,
        selector: Optional[str] = None,
        full_page: bool = False
    ) -> str:
        """
        Capture a screenshot of the current page or specific element.

        Args:
            selector: CSS selector to capture a specific element. If None,
                     captures the viewport.
            full_page: If True, captures the full scrollable page content.
                      Ignored if selector is provided.

        Returns:
            Path to saved screenshot (LOCAL) or URL (REMOTE).
        """
        pass

    @abstractmethod
    async def get_dom_snapshot(self) -> str:
        """
        Get the current DOM state as an HTML string.

        Returns:
            String containing the outer HTML of the document.
        """
        pass

    @abstractmethod
    async def get_errors(
        self,
        severity: Optional[str] = None,
        limit: int = 50
    ) -> List[Dict[str, Any]]:
        """
        Retrieve accumulated browser errors (console errors, crashes, network failures).

        Args:
            severity: Filter by error severity.
            limit: Maximum number of errors to return.

        Returns:
            List of error details.
        """
        pass

    @abstractmethod
    async def run_accessibility_audit(
        self,
        selector: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Run accessibility audit using axe-core.

        Args:
            selector: CSS selector to audit specific element. If None, audits entire page.

        Returns:
            Dictionary with audit results containing:
            - violations: List of accessibility violations
            - passes: List of passing rules
            - incomplete: List of rules needing review
        """
        pass

    @abstractmethod
    async def get_performance_metrics(self) -> Dict[str, Any]:
        """
        Get performance metrics including Core Web Vitals.

        Returns:
            Dictionary containing:
            - navigation_timing: Navigation Timing API data
            - core_web_vitals: TTFB, FCP, LCP, CLS metrics
        """
        pass


class FilesystemStrategy(ABC):
    """
    Abstract base strategy for filesystem operations.

    Provides methods for reading and searching files.
    Implementations ensure safe access to the filesystem in Local mode
    or proxy requests in Remote mode.
    """

    @abstractmethod
    async def read_file(self, path: str) -> str:
        """
        Read the contents of a file.

        Args:
            path: Relative or absolute path to the file.

        Returns:
            File content as string.

        Raises:
            FileNotFoundError: If the file does not exist.
        """
        pass

    @abstractmethod
    async def list_directory(self, path: str) -> List[str]:
        """
        List contents of a directory.

        Args:
            path: Directory path.

        Returns:
            List of filenames and directory names in the path.
        """
        pass

    @abstractmethod
    async def search_files(self, pattern: str, path: str = ".") -> List[str]:
        """
        Search for files matching a pattern.

        Args:
            pattern: Search pattern (glob or regex depending on implementation).
            path: Root path to start search from.

        Returns:
            List of matching file paths.
        """
        pass

    @abstractmethod
    async def get_file_info(self, path: str) -> Dict[str, Any]:
        """
        Get metadata about a file.

        Args:
            path: File path.

        Returns:
            Dictionary containing metadata (size, created_at, modified_at).
        """
        pass
