"""
Context access utilities and helpers.

This module provides convenient access to MCP Context data and common
operations that services need to perform with the context.
"""

import os
from typing import Optional
from mcp.server.fastmcp import Context

from ..project_settings import ProjectSettings


class ContextHelper:
    """
    Helper class for convenient access to MCP Context data.

    This class wraps the MCP Context object and provides convenient properties
    and methods for accessing commonly needed data like base_path, settings, etc.
    """

    def __init__(self, ctx: Context):
        """
        Initialize the context helper.

        Args:
            ctx: The MCP Context object
        """
        self.ctx = ctx

    @property
    def base_path(self) -> str:
        """
        Get the base project path from the context.

        Returns:
            The base project path, or empty string if not set
        """
        try:
            return self.ctx.request_context.lifespan_context.base_path
        except AttributeError:
            return ""

    @property
    def settings(self) -> Optional[ProjectSettings]:
        """
        Get the project settings from the context.

        Returns:
            The ProjectSettings instance, or None if not available
        """
        try:
            return self.ctx.request_context.lifespan_context.settings
        except AttributeError:
            return None

    @property
    def file_count(self) -> int:
        """
        Get the current file count from the context.

        Returns:
            The number of indexed files, or 0 if not available
        """
        try:
            return self.ctx.request_context.lifespan_context.file_count
        except AttributeError:
            return 0

    @property
    def index_manager(self):
        """
        Get the unified index manager from the context.

        Returns:
            The UnifiedIndexManager instance, or None if not available
        """
        try:
            return getattr(self.ctx.request_context.lifespan_context, 'index_manager', None)
        except AttributeError:
            return None

    def validate_base_path(self) -> bool:
        """
        Check if the base path is set and valid.

        Returns:
            True if base path is set and exists, False otherwise
        """
        base_path = self.base_path
        return bool(base_path and os.path.exists(base_path))

    def get_base_path_error(self) -> Optional[str]:
        """
        Get an error message if base path is not properly set.

        Returns:
            Error message string if base path is invalid, None if valid
        """
        if not self.base_path:
            return ("Project path not set. Please use set_project_path to set a "
                    "project directory first.")

        if not os.path.exists(self.base_path):
            return f"Project path does not exist: {self.base_path}"

        if not os.path.isdir(self.base_path):
            return f"Project path is not a directory: {self.base_path}"

        return None

    def update_file_count(self, count: int) -> None:
        """
        Update the file count in the context.

        Args:
            count: The new file count
        """
        try:
            self.ctx.request_context.lifespan_context.file_count = count
        except AttributeError:
            pass  # Context not available or doesn't support this operation

    def update_base_path(self, path: str) -> None:
        """
        Update the base path in the context.

        Args:
            path: The new base path
        """
        try:
            self.ctx.request_context.lifespan_context.base_path = path
        except AttributeError:
            pass  # Context not available or doesn't support this operation

    def update_settings(self, settings: ProjectSettings) -> None:
        """
        Update the settings in the context.

        Args:
            settings: The new ProjectSettings instance
        """
        try:
            self.ctx.request_context.lifespan_context.settings = settings
        except AttributeError:
            pass  # Context not available or doesn't support this operation

    def clear_index_cache(self) -> None:
        """
        Clear the index through the unified index manager.
        """
        try:
            if self.index_manager:
                self.index_manager.clear_index()
        except AttributeError:
            pass
    
    def update_index_manager(self, index_manager) -> None:
        """
        Update the index manager in the context.

        Args:
            index_manager: The new UnifiedIndexManager instance
        """
        try:
            self.ctx.request_context.lifespan_context.index_manager = index_manager
        except AttributeError:
            pass  # Context not available or doesn't support this operation
