"""
ACT Protocol: 数据类、枚举与异常
"""

from dataclasses import dataclass, field, asdict
from typing import Any, Dict, Optional
from enum import Enum

# ------------------------ 异常体系 ------------------------
class ACTError(Exception):
    """ACT Kernel 基础异常"""
    pass

class ExecutionError(ACTError):
    pass

class TimeoutError(ExecutionError):
    pass

class CircuitOpenError(ExecutionError):
    pass

class RetryExhaustedError(ExecutionError):
    pass

class ToolError(ACTError):
    pass

class ToolUnavailableError(ToolError):
    pass

class ACTPermissionError(ACTError):
    pass

class ResourceExhaustedError(ACTError):
    pass

# ------------------------ 枚举定义 ------------------------
class Status(str, Enum):
    OK = "ok"
    TIMEOUT = "timeout"
    ERROR = "error"
    REJECTED = "rejected"
    DEGRADED = "degraded"

class BreakerState(str, Enum):
    CLOSED = "closed"
    OPEN = "open"
    HALF_OPEN = "half-open"

# ------------------------ 数据结构 ------------------------
@dataclass
class ExecutionInfo:
    status: Status = Status.OK
    latency_ms: int = 0
    queue_ms: int = 0
    retries: int = 0
    breaker_state: BreakerState = BreakerState.CLOSED
    timeout_ms: int = 0
    cached: bool = False
    quota_requested: int = 0
    quota_consumed: int = 0
    quota_remaining: int = 0
    node: str = "local"

@dataclass
class Envelope:
    version: str = "1.0"
    intent: Dict[str, Any] = field(default_factory=dict)
    execution: ExecutionInfo = field(default_factory=ExecutionInfo)
    payload: Optional[Any] = None
    error: Optional[Dict[str, Any]] = None

    def to_dict(self) -> Dict[str, Any]:
        d = asdict(self)
        d["execution"]["status"] = d["execution"]["status"].value
        d["execution"]["breaker_state"] = d["execution"]["breaker_state"].value
        return d

def error_code_from_exception(e: Exception) -> str:
    """Map exception to error code."""
    if isinstance(e, TimeoutError):
        return "execution.timeout"
    if isinstance(e, CircuitOpenError):
        return "execution.circuit_open"
    if isinstance(e, RetryExhaustedError):
        return "execution.retry_exhausted"
    if isinstance(e, ACTPermissionError):
        return "permission.denied"
    if isinstance(e, ToolUnavailableError):
        return "tool.unavailable"
    if isinstance(e, ToolError):
        return "tool.error"
    if isinstance(e, ValueError) or isinstance(e, TypeError):
        return "validation.invalid_params"
    return "internal.error"
