# -*- coding: utf-8 -*-
"""
子 Agent 启动工具
主 Agent 通过调用此工具启动一个或多个子 Agent 并行执行独立子任务。
"""
from typing import Any, Dict, List

from ..config import Config
from ..subagent.runner import SubAgentRunner
from .base import Tool, coerce_list_of_dicts

# 单次调用允许的最大子任务数（防止 AI 滥用导致 API 限流/资源耗尽）
MAX_TASKS_PER_CALL = 8


class SpawnSubagentsTool(Tool):
    """子 Agent 启动工具：主 Agent 调用此工具并行启动多个子 Agent。

    子任务必须相互独立、无依赖关系。每个子 Agent 拥有完整工具集（除本工具），
    结果按输入顺序汇总返回给主 Agent。
    """

    def __init__(self, cfg: Config = None, working_dir: str = "."):
        self._cfg = cfg
        self._working_dir = working_dir
        # 延迟初始化 Runner，避免无 cfg 时（如 schema 检查）报错
        self._runner = None

    @property
    def name(self) -> str:
        """工具名称"""
        return "spawn_subagents"

    @property
    def description(self) -> str:
        """工具功能描述"""
        return (
            "启动一个或多个子 Agent 并行执行独立的复杂/重复子任务。"
            "适用场景：任务可拆分为多个无依赖的子任务、重复性操作需并行加速。"
            "限制：子任务必须相互独立（一个子任务的结果不能是另一个的输入），"
            "子任务描述必须自包含（含完整上下文）。单次调用最多 8 个子任务。"
        )

    @property
    def parameters(self) -> Dict[str, Any]:
        """工具参数 JSON Schema"""
        return {
            "type": "object",
            "properties": {
                "tasks": {
                    "type": "array",
                    "description": "要并行执行的子任务列表",
                    "items": {
                        "type": "object",
                        "properties": {
                            "task": {
                                "type": "string",
                                "description": "明确、自包含的子任务描述"
                            },
                            "context": {
                                "type": "string",
                                "description": "可选上下文（相关文件路径、背景信息）"
                            },
                            "methodology": {
                                "type": "string",
                                "description": "可选方法论纪律：debug（调试纪律）、architecture（架构改进）、prototype（原型纪律）。指定后子 Agent 在 system prompt 中追加对应方法论。",
                                "enum": ["debug", "architecture", "prototype"]
                            }
                        },
                        "required": ["task"]
                    },
                    "minItems": 1,
                    "maxItems": MAX_TASKS_PER_CALL
                }
            },
            "required": ["tasks"]
        }

    def execute(self, tasks: List[Dict[str, str]]) -> Dict[str, Any]:
        """执行子 Agent 并行任务，返回汇总结果。

        Args:
            tasks: 子任务列表，每项含 task（必填）和 context（可选）

        Returns:
            success=True 时含 results 列表和 summary；success=False 时含 error
        """
        if not tasks:
            return {"success": False, "error": "任务列表不能为空"}

        # 兼容 LLM 将 tasks 序列化为 JSON 字符串的情形
        tasks = coerce_list_of_dicts(tasks)

        if not tasks:
            return {"success": False, "error": "任务列表不能为空"}

        if len(tasks) > MAX_TASKS_PER_CALL:
            return {
                "success": False,
                "error": f"子任务数量超过上限 {MAX_TASKS_PER_CALL}，当前 {len(tasks)} 个"
            }

        if self._runner is None:
            self._runner = SubAgentRunner(
                cfg=self._cfg, working_dir=self._working_dir
            )

        results = self._runner.run_parallel(tasks)
        summary = self._build_summary(results)

        return {
            "success": True,
            "results": results,
            "summary": summary
        }

    @staticmethod
    def _build_summary(results: List[str]) -> str:
        """汇总子 Agent 结果，生成简要摘要供主 Agent 快速参考"""
        count = len(results)
        success_count = sum(1 for r in results if "失败" not in r and "错误" not in r)
        return f"共 {count} 个子任务完成，成功 {success_count} 个"
