"""File listing tools for OpenZIM MCP server."""

import logging
from typing import TYPE_CHECKING, Union

from ..constants import INPUT_LIMIT_QUERY
from ..exceptions import OpenZimMcpRateLimitError
from ..responses import ToolErrorPayload, tool_error
from ..security import sanitize_input
from ..tool_schemas import ListZimFilesResponse

if TYPE_CHECKING:
    from ..server import OpenZimMcpServer

logger = logging.getLogger(__name__)


def register_file_tools(server: "OpenZimMcpServer") -> None:
    """
    Register file listing tools.

    Args:
        server: The OpenZimMcpServer instance to register tools on
    """

    @server.mcp.tool()
    async def list_zim_files(
        name_filter: str = "",
    ) -> Union[ListZimFilesResponse, ToolErrorPayload]:
        """List all ZIM files in allowed directories.

        Args:
            name_filter: Optional case-insensitive substring; only files whose
                filename contains it are returned. Use this to narrow large
                listings (e.g. "wikipedia", "nginx"). Empty string lists all.

        Returns:
            ``ListZimFilesResponse``-shaped dict carrying ``results`` (per-file
            dicts: name, path, directory, size, size_bytes, modified),
            ``next_cursor`` (always ``None``), ``total``, ``done`` (always
            ``True``), ``page_info``, plus the tool-specific
            ``directories_count`` and ``name_filter`` fields and the ``_meta``
            envelope. ``list_zim_files`` is non-paginated; the contract keys
            are present for uniformity with other list-shaped tools. On
            failure, returns a ``ToolErrorPayload`` envelope (see
            ``responses.tool_error``).
        """
        try:
            try:
                server.rate_limiter.check_rate_limit("default")
            except OpenZimMcpRateLimitError as e:
                return tool_error(
                    operation="list ZIM files",
                    message=server._create_enhanced_error_message(
                        operation="list ZIM files",
                        error=e,
                        context="Listing available ZIM files",
                    ),
                    context="Listing available ZIM files",
                )

            # Strip control characters and cap length, matching the
            # input-validation pattern every other tool applies. The
            # backend uses ``name_filter`` as a substring match; an
            # un-sanitized value carrying control characters would land
            # in logs verbatim and bypass the consistency every other
            # tool input enjoys.
            name_filter = sanitize_input(
                name_filter, INPUT_LIMIT_QUERY, allow_empty=True
            )

            return await server.async_zim_operations.list_zim_files_summary_data(
                name_filter=name_filter
            )

        except Exception as e:
            logger.error(f"Error listing ZIM files: {e}")
            return tool_error(
                operation="list ZIM files",
                message=server._create_enhanced_error_message(
                    operation="list ZIM files",
                    error=e,
                    context="Scanning allowed directories for ZIM files",
                ),
                context="Scanning allowed directories for ZIM files",
            )
