# -*- coding: utf-8 -*-
"""
文件编辑工具
通过搜索替换修改文件内容
"""
from .base import Tool
from .file_cache import get_default_cache
from .file_io import AtomicFileWriter, EncodingDetector
from ..security.path_security import get_default_service as get_path_security


class FileEditTool(Tool):
    """通过搜索替换修改文件内容的工具。"""

    @property
    def name(self) -> str:
        return "file_edit"

    @property
    def description(self) -> str:
        return "修改已有文件的指定内容，通过精确匹配旧字符串替换为新字符串。"

    @property
    def parameters(self) -> dict:
        return {
            "type": "object",
            "properties": {
                "path": {"type": "string", "description": "文件路径"},
                "old_str": {"type": "string", "description": "要替换的旧内容"},
                "new_str": {"type": "string", "description": "替换后的新内容"}
            },
            "required": ["path", "old_str", "new_str"]
        }

    def execute(self, path: str, old_str: str, new_str: str) -> dict:
        """编辑文件内容"""
        # PathSecurityService 5 重校验（Phase 6 Tier 1-5 AP）
        sec = get_path_security()
        check = sec.check_write(path)
        if not check.allowed:
            # 保持与历史断言一致："禁止写入" → "禁止编辑"
            reason = check.reason.replace("禁止写入", "禁止编辑")
            return {"success": False, "error": reason}
        if check.needs_confirmation:
            return {"success": False, "error": f"需用户确认: {check.reason}"}

        try:
            # 检测文件编码（Phase 6 Tier 1-3 AO）
            encoding = EncodingDetector.detect(path)
            if encoding is None:
                return {"success": False, "error": "无法编辑二进制文件"}

            # 用检测到的编码读取
            with open(path, "r", encoding=encoding) as f:
                content = f.read()

            if old_str not in content:
                return {"success": False, "error": "未找到匹配的旧内容"}

            new_content = content.replace(old_str, new_str, 1)

            # 使用 AtomicFileWriter 原子写入（保持原编码）
            AtomicFileWriter.write(path, new_content, encoding=encoding)

            # 失效文件状态缓存（Phase 6 AQ）
            get_default_cache().invalidate(path)

            return {"success": True, "path": path, "encoding": encoding}
        except Exception as e:
            return {"success": False, "error": str(e)}
