from __future__ import annotations

from collections.abc import Mapping

from ..agent_tool_core import AgentTool, ToolHandler
from ._builder import resolve_handler


def build_file_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentTool]:
    """构建工作区文件读写与文本检索工具声明。"""

    return [
        AgentTool(
            name='list_dir',
            description='List files and directories under a workspace path.',
            parameters={
                'type': 'object',
                'properties': {
                    'path': {'type': 'string', 'description': 'Relative path from workspace root.'},
                    'max_entries': {'type': 'integer', 'minimum': 1, 'maximum': 500},
                },
            },
            handler=resolve_handler(handlers, 'list_dir', 'file'),
        ),
        AgentTool(
            name='read_file',
            description='Read the contents of a UTF-8 text file inside the workspace.',
            parameters={
                'type': 'object',
                'properties': {
                    'path': {'type': 'string', 'description': 'Relative file path from workspace root.'},
                    'start_line': {'type': 'integer', 'minimum': 1},
                    'end_line': {'type': 'integer', 'minimum': 1},
                },
                'required': ['path'],
            },
            handler=resolve_handler(handlers, 'read_file', 'file'),
        ),
        AgentTool(
            name='write_file',
            description=(
                'Write or append a SMALL UTF-8 file inside the workspace. Creates parent directories when needed. '
                'Use this for short notes, lightweight markdown, and small config files. '
                'For Python scripts, JSONL, large JSON/CSV, generated datasets, or quote-heavy/multi-line content, prefer python_exec '
                'to write the file with pathlib/json/csv; do not pack large content into tool arguments.'
            ),
            parameters={
                'type': 'object',
                'properties': {
                    'path': {'type': 'string', 'description': 'Relative path. output/, scratchpad/, and input/ route to the current session.'},
                    'content_lines': {
                        'type': 'array',
                        'items': {'type': 'string'},
                        'description': 'Lines to join with "\\n"; use only for short text/markdown or small scripts. For long scripts use python_exec to create the file.',
                    },
                    'content': {
                        'type': 'string',
                        'description': 'Short one-line/simple text only. Never use for multi-line scripts, JSON, JSONL, CSV, or quote-heavy content.',
                    },
                    'content_base64': {
                        'type': 'string',
                        'description': 'Base64-encoded UTF-8 content. Use only if the content is already available as base64.',
                    },
                    'json_content': {
                        'type': 'object',
                        'description': 'Small JSON value to serialize with ensure_ascii=false and indent=2. For large JSON use python_exec streaming write.',
                    },
                    'jsonl_records': {
                        'type': 'array',
                        'items': {'type': 'object'},
                        'description': 'Small list of objects to serialize as compact JSONL. For more than a few dozen records or generated datasets use python_exec.',
                    },
                    'csv_headers': {
                        'type': 'array',
                        'items': {'type': 'string'},
                        'description': 'Optional CSV header order. Use with csv_rows.',
                    },
                    'csv_rows': {
                        'type': 'array',
                        'items': {
                            'type': 'array',
                            'items': {'type': 'string'},
                        },
                        'description': 'Rows to serialize as CSV. Each row is an array of cell strings.',
                    },
                    'append': {
                        'type': 'boolean',
                        'description': 'Append to an existing file instead of replacing it. Defaults to false.',
                    },
                    'newline_at_end': {
                        'type': 'boolean',
                        'description': 'Ensure the written text ends with a newline. Defaults to false.',
                    },
                },
                'required': ['path'],
            },
            handler=resolve_handler(handlers, 'write_file', 'file'),
        ),
        AgentTool(
            name='edit_file',
            description='Replace text inside a workspace file using exact string matching.',
            parameters={
                'type': 'object',
                'properties': {
                    'path': {'type': 'string'},
                    'old_text': {'type': 'string'},
                    'new_text': {'type': 'string'},
                    'replace_all': {'type': 'boolean'},
                },
                'required': ['path', 'old_text', 'new_text'],
            },
            handler=resolve_handler(handlers, 'edit_file', 'file'),
        ),
        AgentTool(
            name='notebook_edit',
            description='Edit a Jupyter notebook cell by replacing or appending source in a .ipynb file.',
            parameters={
                'type': 'object',
                'properties': {
                    'path': {'type': 'string'},
                    'cell_index': {'type': 'integer', 'minimum': 0},
                    'source': {'type': 'string'},
                    'cell_type': {'type': 'string'},
                    'create_cell': {'type': 'boolean'},
                },
                'required': ['path', 'cell_index', 'source'],
            },
            handler=resolve_handler(handlers, 'notebook_edit', 'file'),
        ),
        AgentTool(
            name='glob_search',
            description='Find files matching a glob pattern inside the workspace.',
            parameters={
                'type': 'object',
                'properties': {
                    'pattern': {'type': 'string'},
                },
                'required': ['pattern'],
            },
            handler=resolve_handler(handlers, 'glob_search', 'file'),
        ),
        AgentTool(
            name='grep_search',
            description='Search for a string or regular expression inside workspace files.',
            parameters={
                'type': 'object',
                'properties': {
                    'pattern': {'type': 'string'},
                    'path': {'type': 'string'},
                    'literal': {'type': 'boolean'},
                    'max_matches': {'type': 'integer', 'minimum': 1, 'maximum': 500},
                },
                'required': ['pattern'],
            },
            handler=resolve_handler(handlers, 'grep_search', 'file'),
        ),
    ]
