"""
agentpaas.engine.confirmations — HIGH-risk 工具调用的人工确认登记处。

SEC-12/SEC-30 闭环（AUDIT_2026-06-11 ③）：lambdagent ToolGateway 在
highRiskConfirmation=true 时对 HIGH 风险工具调用产生 Action.CONFIRM，
并调用 policy.confirm_callback(tool, input, reason) -> bool 决定放行。

这里提供宿主侧实现：agent 执行线程调用 request_confirmation() 登记
待确认项并阻塞等待；用户通过 POST /api/v1/traces/{run_id}/confirm
（traces.py）调用 resolve() 放行或拒绝。超时（默认 5 分钟）按拒绝处理
—— 与 ToolGateway 的 fail-closed 语义一致。

每个 run 同一时刻最多一个待确认项（agent 线程在等待期间是阻塞的）。
"""
from __future__ import annotations

import threading
import time
from typing import Any, Dict, Optional

_lock = threading.Lock()
_pending: Dict[str, Dict[str, Any]] = {}  # run_id -> entry

DEFAULT_TIMEOUT_S = 300  # 5 分钟无人确认 → 拒绝


def request_confirmation(run_id: str, tool_name: str, input_str: str,
                         reason: str, timeout_s: float = DEFAULT_TIMEOUT_S) -> bool:
    """登记一个待确认项并阻塞等待用户决定。

    Returns True 放行 / False 拒绝（含超时、run_id 缺失）。
    在 agent 执行线程内调用，绝不抛异常。
    """
    if not run_id:
        return False  # 无 run 上下文无法路由确认 → fail-closed
    event = threading.Event()
    entry: Dict[str, Any] = {
        "tool": tool_name,
        "input": str(input_str)[:2000],
        "reason": reason,
        "event": event,
        "decision": None,
        "requested_at": time.time(),
    }
    with _lock:
        _pending[run_id] = entry
    try:
        event.wait(timeout_s)
    finally:
        with _lock:
            if _pending.get(run_id) is entry:
                del _pending[run_id]
    return bool(entry["decision"])


def resolve(run_id: str, approved: bool) -> bool:
    """用户对 run 的待确认项做出决定。Returns False 表示没有待确认项。"""
    with _lock:
        entry = _pending.get(run_id)
    if not entry:
        return False
    entry["decision"] = bool(approved)
    entry["event"].set()
    return True


def get_pending(run_id: str) -> Optional[Dict[str, Any]]:
    """查询 run 当前的待确认项（无则 None）。不含内部 event 对象。"""
    with _lock:
        entry = _pending.get(run_id)
    if not entry:
        return None
    return {
        "tool": entry["tool"],
        "input": entry["input"],
        "reason": entry["reason"],
        "requested_at": entry["requested_at"],
    }
