"""文件操作工具 - Phase 6.4"""

import os
from typing import Any

from app.agents.tools.base import ExternalTool, ReadTool, WriteTool
from app.agents.tools.manifest import (
    PermissionClass,
    SideEffectScope,
    ToolCategory,
)


class GlobTool(ReadTool):
    """文件路径匹配工具

    使用 glob 模式查找文件。
    """

    def __init__(self, root_dir: str = "."):
        super().__init__(
            name="glob",
            description="使用 glob 模式查找文件路径",
            permission_class=PermissionClass.READ,
            side_effect_scope=SideEffectScope.NONE,
            tags=["file", "search", "glob"],
        )
        self.root_dir = root_dir

    def get_parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "pattern": {
                    "type": "string",
                    "description": "Glob 模式，如 **/*.py",
                },
                "root_dir": {
                    "type": "string",
                    "description": "搜索根目录（可选）",
                },
            },
            "required": ["pattern"],
        }

    def get_return_schema(self) -> dict[str, Any]:
        return {
            "type": "array",
            "items": {"type": "string"},
        }

    async def execute(self, pattern: str, root_dir: str | None = None) -> list[str]:
        import glob as glob_module

        root = root_dir or self.root_dir
        return glob_module.glob(pattern, root_dir=root, recursive=True)


class GrepTool(ReadTool):
    """文件内容搜索工具

    在文件中搜索匹配的行。
    """

    def __init__(self):
        super().__init__(
            name="grep",
            description="在文件中搜索匹配的文本行",
            permission_class=PermissionClass.READ,
            side_effect_scope=SideEffectScope.NONE,
            tags=["file", "search", "text"],
        )

    def get_parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "pattern": {
                    "type": "string",
                    "description": "正则表达式模式",
                },
                "paths": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "要搜索的文件路径列表",
                },
                "case_sensitive": {
                    "type": "boolean",
                    "description": "是否区分大小写",
                },
            },
            "required": ["pattern", "paths"],
        }

    def get_return_schema(self) -> dict[str, Any]:
        return {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "file": {"type": "string"},
                    "line": {"type": "integer"},
                    "content": {"type": "string"},
                },
            },
        }

    async def execute(
        self, pattern: str, paths: list[str], case_sensitive: bool = True
    ) -> list[dict[str, Any]]:
        import re

        flags = 0 if case_sensitive else re.IGNORECASE
        regex = re.compile(pattern, flags)
        results = []

        for path in paths:
            if not os.path.isfile(path):
                continue

            try:
                with open(path, "r", encoding="utf-8") as f:
                    for line_num, line in enumerate(f, 1):
                        if regex.search(line):
                            results.append(
                                {
                                    "file": path,
                                    "line": line_num,
                                    "content": line.rstrip(),
                                }
                            )
            except (UnicodeDecodeError, PermissionError):
                continue

        return results


class ReadFileTool(ReadTool):
    """文件读取工具"""

    def __init__(self):
        super().__init__(
            name="read_file",
            description="读取文件内容",
            permission_class=PermissionClass.READ,
            side_effect_scope=SideEffectScope.NONE,
            tags=["file", "read"],
        )

    def get_parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "文件路径",
                },
                "limit": {
                    "type": "integer",
                    "description": "最大行数",
                },
                "offset": {
                    "type": "integer",
                    "description": "起始行号",
                },
            },
            "required": ["path"],
        }

    def get_return_schema(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "content": {"type": "string"},
                "lines": {"type": "integer"},
            },
        }

    async def execute(self, path: str, limit: int | None = None, offset: int = 0) -> dict[str, Any]:
        if not os.path.isfile(path):
            raise FileNotFoundError(f"File not found: {path}")

        with open(path, "r", encoding="utf-8") as f:
            lines = f.readlines()

        total_lines = len(lines)
        start = max(0, offset)
        end = len(lines) if limit is None else min(start + limit, len(lines))

        content = "".join(lines[start:end])

        return {
            "content": content,
            "lines": total_lines,
            "truncated": limit is not None and end < len(lines),
        }


class WriteFileTool(WriteTool):
    """文件写入工具"""

    def __init__(self):
        super().__init__(
            name="write_file",
            description="写入文件内容",
            permission_class=PermissionClass.WRITE,
            side_effect_scope=SideEffectScope.LOCAL_STATE,
            requires_confirmation=True,
            tags=["file", "write"],
        )

    def get_parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "文件路径",
                },
                "content": {
                    "type": "string",
                    "description": "文件内容",
                },
                "append": {
                    "type": "boolean",
                    "description": "是否追加模式",
                },
            },
            "required": ["path", "content"],
        }

    def get_return_schema(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "success": {"type": "boolean"},
                "bytes_written": {"type": "integer"},
            },
        }

    async def execute(self, path: str, content: str, append: bool = False) -> dict[str, Any]:
        mode = "a" if append else "w"

        # 确保目录存在
        directory = os.path.dirname(path)
        if directory and not os.path.exists(directory):
            os.makedirs(directory, exist_ok=True)

        with open(path, mode, encoding="utf-8") as f:
            bytes_written = f.write(content)

        return {
            "success": True,
            "bytes_written": bytes_written,
        }
