"""
Direct Executor - 直接执行器
用于低风险任务，直接执行不隔离
"""

import asyncio
import os
import shutil
import tempfile
from pathlib import Path
from typing import AsyncGenerator

from app.agents.tools.ai_adapter import AICLIAdapter


class ExecutionResult:
    """执行结果"""

    def __init__(
        self,
        success: bool,
        exit_code: int,
        stdout: str,
        stderr: str,
    ):
        self.success = success
        self.exit_code = exit_code
        self.stdout = stdout
        self.stderr = stderr


class DirectExecutor:
    """直接执行器（用于低风险任务）"""

    def __init__(self, adapter: AICLIAdapter, timeout: int = 60):
        self.adapter = adapter
        self.timeout = timeout

    async def execute(
        self,
        prompt: str,
    ) -> AsyncGenerator[str, None]:
        """
        直接执行，不需要沙盒

        Args:
            prompt: 任务描述

        Yields:
            str: 实时输出
        """
        # 1. 检查 CLI 是否安装
        if not self.adapter.is_installed():
            yield f"[ERROR] {self.adapter.cli_name} is not installed\n"
            yield f"[ERROR] Please install {self.adapter.cli_name} first\n"
            return

        # 2. 构建命令
        cmd = self.adapter.build_command(prompt, None)

        # 3. 异步执行，实时 yield 输出
        process = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
            env={**os.environ, "TERM": "xterm-256color"},
        )

        # 4. 实时读取输出
        stdout_lines = []
        stderr_lines = []

        while True:
            try:
                line_bytes = await asyncio.wait_for(
                    process.stdout.readline(),
                    timeout=self.timeout,
                )
                if not line_bytes:
                    break
                line = line_bytes.decode("utf-8", errors="replace")
                stdout_lines.append(line)
                yield line
            except asyncio.TimeoutError:
                process.kill()
                yield f"\n[ERROR] Execution timed out after {self.timeout}s\n"
                break

        # 5. 读取 stderr
        stderr_bytes = await process.communicate()
        if stderr_bytes[1]:
            stderr = stderr_bytes[1].decode("utf-8", errors="replace")
            stderr_lines.append(stderr)
            yield f"\n[STDERR]\n{stderr}\n"

        # 6. 完成标记
        yield f"\n[EXIT_CODE] {process.returncode or 0}\n"
        yield f"\n[COMPLETE] success={process.returncode == 0}\n"

    async def execute_sync(self, prompt: str) -> ExecutionResult:
        """同步执行并返回完整结果"""
        output_parts = []
        async for line in self.execute(prompt):
            output_parts.append(line)

        output = "".join(output_parts)
        return ExecutionResult(
            success="[COMPLETE] success=True" in output,
            exit_code=0,
            stdout=output,
            stderr="",
        )
