"""
动态执行管理器
用于在任务执行过程中动态追加新步骤
"""

import asyncio
from typing import Dict, List, Optional, Any
from threading import Lock


class DynamicExecutionManager:
    """
    动态执行管理器
    管理正在执行的任务，支持动态追加新步骤
    """

    def __init__(self):
        # 执行状态: goal -> execution_info
        self._executions: Dict[str, Dict] = {}

        # 线程锁
        self._lock = Lock()

        # 步骤队列: goal -> List[step]
        self._step_queues: Dict[str, List] = {}

        # 已执行的步骤索引: goal -> Set[step_index]
        self._executed_steps: Dict[str, set] = {}

        # 待执行的步骤索引: goal -> List[step_index]
        self._pending_steps: Dict[str, List[int]] = {}

    def start_execution(self, goal: str, initial_steps: List[Dict], execution_id: str = None) -> str:
        """
        开始执行一个新的任务

        Args:
            goal: 任务目标
            initial_steps: 初始步骤列表
            execution_id: 执行ID，如果不提供则自动生成

        Returns:
            执行ID
        """
        with self._lock:
            # 如果未提供execution_id，则生成一个
            if execution_id is None:
                execution_id = f"{goal}_{asyncio.get_event_loop().time()}"

            self._executions[execution_id] = {
                "goal": goal,
                "status": "running",
                "total_steps": len(initial_steps),
                "completed_steps": 0
            }

            # 初始化步骤队列
            self._step_queues[execution_id] = initial_steps.copy()

            # 初始化已执行步骤集合
            self._executed_steps[execution_id] = set()

            # 初始化待执行步骤索引
            self._pending_steps[execution_id] = list(range(len(initial_steps)))

            print(f"[Execution] 启动执行: {execution_id}, 步骤数={len(initial_steps)}")
            return execution_id

    def add_steps(self, execution_id: str, new_steps: List[Dict]) -> int:
        """
        向执行中追加新步骤

        Args:
            execution_id: 执行ID
            new_steps: 新步骤列表

        Returns:
            追加的步骤数量
        """
        with self._lock:
            if execution_id not in self._step_queues:
                return 0

            current_count = len(self._step_queues[execution_id])

            # 追加新步骤到队列
            self._step_queues[execution_id].extend(new_steps)

            # 添加新步骤的索引到待执行列表
            new_indices = list(range(current_count, current_count + len(new_steps)))
            self._pending_steps[execution_id].extend(new_indices)

            # 更新总步骤数
            self._executions[execution_id]["total_steps"] = len(self._step_queues[execution_id])

            print(f"[Execution] 追加步骤: +{len(new_steps)}, 总计={self._executions[execution_id]['total_steps']}")
            return len(new_steps)

    def get_next_step(self, execution_id: str) -> Optional[Dict]:
        """
        获取下一个待执行的步骤

        Args:
            execution_id: 执行ID

        Returns:
            下一个步骤，如果没有则返回None
        """
        with self._lock:
            if execution_id not in self._pending_steps:
                return None

            # 获取第一个待执行步骤的索引
            if not self._pending_steps[execution_id]:
                return None

            step_index = self._pending_steps[execution_id].pop(0)

            # 从队列中获取步骤
            if step_index >= len(self._step_queues[execution_id]):
                return None

            step = self._step_queues[execution_id][step_index]

            # 标记为已执行
            self._executed_steps[execution_id].add(step_index)

            step_name = step.get("StepName", "未知")
            print(f"[Execution] 获取步骤: {step_name} (索引: {step_index})")
            return step

    def mark_step_completed(self, execution_id: str):
        """
        标记一个步骤完成

        Args:
            execution_id: 执行ID
        """
        with self._lock:
            if execution_id in self._executions:
                self._executions[execution_id]["completed_steps"] += 1
                completed = self._executions[execution_id]["completed_steps"]
                total = self._executions[execution_id]["total_steps"]
                print(f"[Execution] 步骤完成: {completed}/{total}")

    def get_execution_info(self, execution_id: str) -> Optional[Dict]:
        """
        获取执行信息

        Args:
            execution_id: 执行ID

        Returns:
            执行信息字典
        """
        with self._lock:
            return self._executions.get(execution_id)

    def get_pending_count(self, execution_id: str) -> int:
        """
        获取待执行步骤数量

        Args:
            execution_id: 执行ID

        Returns:
            待执行步骤数量
        """
        with self._lock:
            if execution_id not in self._pending_steps:
                return 0
            return len(self._pending_steps[execution_id])

    def has_more_steps(self, execution_id: str) -> bool:
        """
        检查是否还有更多步骤待执行

        Args:
            execution_id: 执行ID

        Returns:
            是否还有待执行步骤
        """
        with self._lock:
            if execution_id not in self._pending_steps:
                return False
            return len(self._pending_steps[execution_id]) > 0

    def finish_execution(self, execution_id: str):
        """
        完成执行

        Args:
            execution_id: 执行ID
        """
        with self._lock:
            if execution_id in self._executions:
                self._executions[execution_id]["status"] = "completed"

    def cancel_execution(self, execution_id: str):
        """
        取消执行

        Args:
            execution_id: 执行ID
        """
        with self._lock:
            if execution_id in self._executions:
                self._executions[execution_id]["status"] = "cancelled"

    def cleanup(self, execution_id: str):
        """
        清理执行记录

        Args:
            execution_id: 执行ID
        """
        with self._lock:
            self._executions.pop(execution_id, None)
            self._step_queues.pop(execution_id, None)
            self._executed_steps.pop(execution_id, None)
            self._pending_steps.pop(execution_id, None)


# 全局单例
dynamic_execution_manager = DynamicExecutionManager()
