"""系统工具 - Phase 6.4"""

import asyncio
import shlex
from typing import Any

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


class BashTool(ExternalTool):
    """Bash 命令执行工具"""

    def __init__(self, working_dir: str = "."):
        super().__init__(
            name="bash",
            description="执行 Bash 命令",
            permission_class=PermissionClass.EXTERNAL,
            side_effect_scope=SideEffectScope.LOCAL_STATE,
            requires_confirmation=True,
            tags=["system", "bash", "shell"],
        )
        self.working_dir = working_dir

    def get_parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "command": {
                    "type": "string",
                    "description": "要执行的 Bash 命令",
                },
                "timeout": {
                    "type": "integer",
                    "description": "超时时间（秒）",
                },
                "working_dir": {
                    "type": "string",
                    "description": "工作目录（可选）",
                },
            },
            "required": ["command"],
        }

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

    async def execute(
        self, command: str, timeout: int = 30, working_dir: str | None = None
    ) -> dict[str, Any]:
        import os

        cwd = working_dir or self.working_dir

        try:
            process = await asyncio.create_subprocess_shell(
                command,
                stdout=asyncio.subprocess.PIPE,
                stderr=asyncio.subprocess.PIPE,
                cwd=cwd,
            )

            try:
                stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=timeout)
            except asyncio.TimeoutError:
                process.kill()
                await process.wait()
                return {
                    "stdout": "",
                    "stderr": f"Command timed out after {timeout} seconds",
                    "returncode": -1,
                }

            return {
                "stdout": stdout.decode("utf-8", errors="replace"),
                "stderr": stderr.decode("utf-8", errors="replace"),
                "returncode": process.returncode,
            }

        except Exception as e:
            return {
                "stdout": "",
                "stderr": str(e),
                "returncode": -1,
            }


class PowerShellTool(ExternalTool):
    """PowerShell 命令执行工具"""

    def __init__(self, working_dir: str = "."):
        super().__init__(
            name="powershell",
            description="执行 PowerShell 命令",
            permission_class=PermissionClass.EXTERNAL,
            side_effect_scope=SideEffectScope.LOCAL_STATE,
            requires_confirmation=True,
            tags=["system", "powershell", "shell"],
        )
        self.working_dir = working_dir

    def get_parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "command": {
                    "type": "string",
                    "description": "要执行的 PowerShell 命令",
                },
                "timeout": {
                    "type": "integer",
                    "description": "超时时间（秒）",
                },
                "working_dir": {
                    "type": "string",
                    "description": "工作目录（可选）",
                },
            },
            "required": ["command"],
        }

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

    async def execute(
        self, command: str, timeout: int = 30, working_dir: str | None = None
    ) -> dict[str, Any]:
        import platform

        # 检测是否是 Windows 平台
        is_windows = platform.system() == "Windows"

        if not is_windows:
            # 非 Windows 平台，可能没有 PowerShell
            return {
                "stdout": "",
                "stderr": "PowerShell is not available on this platform",
                "returncode": -1,
            }

        cwd = working_dir or self.working_dir

        try:
            process = await asyncio.create_subprocess_exec(
                "powershell.exe",
                "-NoProfile",
                "-Command",
                command,
                stdout=asyncio.subprocess.PIPE,
                stderr=asyncio.subprocess.PIPE,
                cwd=cwd,
            )

            try:
                stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=timeout)
            except asyncio.TimeoutError:
                process.kill()
                await process.wait()
                return {
                    "stdout": "",
                    "stderr": f"Command timed out after {timeout} seconds",
                    "returncode": -1,
                }

            return {
                "stdout": stdout.decode("utf-8", errors="replace"),
                "stderr": stderr.decode("utf-8", errors="replace"),
                "returncode": process.returncode,
            }

        except Exception as e:
            return {
                "stdout": "",
                "stderr": str(e),
                "returncode": -1,
            }
