"""
IProposalEngine - 決策提案引擎介面
==================================

定義 Proposal 生成的標準介面

統帥鐵律:
- 所有 Proposal 必須包含 Guardrails
- 禁止跳過 TrustEngine 評估
- 所有決策必須可稽核
"""

from abc import ABC, abstractmethod
from typing import Any, Protocol
from pydantic import BaseModel


class Proposal(BaseModel):
    """決策提案資料結構"""
    proposal_id: str
    incident_id: str
    action: str
    description: str
    risk_level: str
    guardrails: dict[str, Any]
    metadata: dict[str, Any] = {}


class Guardrails(BaseModel):
    """安全護欄配置"""
    require_dry_run: bool = True
    allowed_namespace: list[str] = ["awoooi-prod"]
    forbidden_commands: list[str] = ["rm -rf", "drop table", "kubectl delete ns"]
    max_retries: int = 1
    timeout_sec: int = 60
    audit_log: str = "mandatory"
    rollback_window_sec: int = 300


class IMemoryProvider(Protocol):
    """記憶體提供者協定 (來自 lewooogo_data)"""
    async def load_incident(self, incident_id: str) -> Any | None: ...
    async def save_incident(self, incident: Any) -> None: ...


class IProposalEngine(ABC):
    """
    決策提案引擎介面

    職責:
    1. 分析 Incident 生成修復建議
    2. 評估風險等級
    3. 建立 ApprovalRequest
    4. 更新 Incident 狀態

    使用方式:
        class MyProposalEngine(IProposalEngine):
            async def generate(self, incident_id: str) -> tuple[Proposal | None, str]:
                # 實作邏輯
                pass
    """

    @abstractmethod
    async def generate(
        self,
        incident_id: str,
    ) -> tuple[Proposal | None, str]:
        """
        生成決策提案

        Args:
            incident_id: 事件 ID

        Returns:
            (Proposal, message) 或 (None, error_message)
        """
        ...

    @abstractmethod
    async def generate_with_skill(
        self,
        incident_id: str,
        skill_id: str,
    ) -> tuple[Proposal | None, str]:
        """
        使用指定 Skill 生成決策提案

        Args:
            incident_id: 事件 ID
            skill_id: Skill 識別碼 (e.g., "04-awoooi-devops-commander")

        Returns:
            (Proposal, message) 或 (None, error_message)
        """
        ...

    @abstractmethod
    def get_default_guardrails(self) -> Guardrails:
        """取得預設安全護欄配置"""
        ...
