"""
Operation Parser Service - Phase 16 R4 瘦身 Router 抽取
=======================================================

從 approvals.py 抽取操作解析邏輯，支援中英文指令格式。

功能:
- 從 action 字串解析 OperationType
- 提取資源名稱與 Namespace
- 支援 kubectl 指令與中文自然語言

版本: v1.0
建立: 2026-03-25 (台北時區)
建立者: Claude Code (Phase 16 R4)
"""

import re
from dataclasses import dataclass

from src.services.executor import OperationType

# 2026-04-06 ogt: Phase 26 — 預設 namespace 改為 awoooi-prod
# 原本 "default" 導致 203 次執行全失敗（deployment 全在 awoooi-prod）
DEFAULT_NAMESPACE = "awoooi-prod"


@dataclass
class ParsedOperation:
    """
    解析後的操作資訊

    Attributes:
        operation_type: K8s 操作類型 (RESTART_DEPLOYMENT, DELETE_POD, etc.)
        resource_name: 目標資源名稱
        namespace: K8s Namespace (預設 "awoooi-prod")

    Note:
        支援 tuple 解包以向後兼容:
        op, resource, ns = parse_operation_from_action(action)
    """

    operation_type: OperationType | None
    resource_name: str | None
    namespace: str

    def __iter__(self):
        """支援 tuple 解包: op, resource, ns = parsed"""
        return iter((self.operation_type, self.resource_name, self.namespace))


def parse_operation_from_action(action: str) -> ParsedOperation:
    """
    從 action 字串解析操作類型與目標資源

    支援格式:
    - kubectl 指令: "kubectl delete pod nginx-xxx -n production"
    - 英文自然語言: "Restart deployment api-backend"
    - 中文自然語言: "重新啟動 awoooi-worker 服務"
    - SSH 指令: "ssh 192.168.0.110 'docker prune ...'" / "ssh wooo@192.168.0.110 ..."

    Examples:
        "kubectl delete pod nginx-xxx -n production"
        → ParsedOperation(DELETE_POD, "nginx-xxx", "production")

        "ssh 192.168.0.110 'docker image prune -a -f'"
        → ParsedOperation(SSH_HOST, "192.168.0.110", "host")

    Args:
        action: 操作指令字串

    Returns:
        ParsedOperation: 解析後的操作資訊
    """
    action_lower = action.lower()

    # 2026-05-02 ogt + Claude Sonnet 4.6: SSH host 操作識別
    # 根因：approval_execution 把 SSH action 丟進 kubectl parser → 全部 None → 「Could not parse」
    # 修法：第一順位偵測 ssh，回 SSH_HOST，approval_execution 走 SSHProvider
    # 支援 "ssh host '...'" / "ssh user@host ..." / "ssh -o opt host ..."
    ssh_match = re.search(
        r"^\s*ssh\s+(?:-[a-zA-Z]\s*\S+\s+)*(?:[a-zA-Z][\w-]*@)?([a-zA-Z0-9][\w.-]*)",
        action_lower,
    )
    if ssh_match:
        host = ssh_match.group(1)
        # namespace 欄位借用為「host_class」，下游不必改
        return ParsedOperation(OperationType.SSH_HOST, host, "host")

    # 2026-04-24 ogt + Claude Sonnet 4.6: Gate 11 修復 — 唯讀指令識別（INVESTIGATE）
    # 根因：parse_operation_from_action 完全不認識 kubectl get/top/describe/logs → 回 None → 執行失敗
    # 修法：優先匹配唯讀指令，回傳 OperationType.INVESTIGATE（零衝擊，blast_radius score=1）
    kubectl_ro_match = re.search(
        r"kubectl\s+(get|top|describe|logs|version)\s*([a-z][\w.-]*)?",
        action_lower,
    )
    if kubectl_ro_match:
        ns_match = re.search(r"-n\s+(\S+)", action_lower)
        namespace = ns_match.group(1) if ns_match else DEFAULT_NAMESPACE
        resource = kubectl_ro_match.group(2) or "pods"
        return ParsedOperation(OperationType.INVESTIGATE, resource, namespace)

    # Pattern: kubectl rollout restart deployment|statefulset|daemonset/<name>
    kubectl_restart_match = re.search(
        r"kubectl\s+rollout\s+restart\s+(deployment|deploy|statefulset|sts|daemonset|ds)/([a-z0-9][\w.-]*)",
        action_lower,
    )
    if kubectl_restart_match:
        resource_type = kubectl_restart_match.group(1)
        resource_name = kubectl_restart_match.group(2)
        ns_match = re.search(r"-n\s+(\S+)", action_lower)
        namespace = ns_match.group(1) if ns_match else DEFAULT_NAMESPACE
        if resource_type in {"statefulset", "sts"}:
            return ParsedOperation(OperationType.RESTART_STATEFULSET, resource_name, namespace)
        if resource_type in {"daemonset", "ds"}:
            return ParsedOperation(OperationType.RESTART_DAEMONSET, resource_name, namespace)
        return ParsedOperation(OperationType.RESTART_DEPLOYMENT, resource_name, namespace)

    # Pattern: kubectl delete pod <name>
    delete_pod_match = re.search(
        r"delete\s+pod[:\s]+([a-z0-9][\w.-]*)", action_lower
    )
    if delete_pod_match:
        pod_name = delete_pod_match.group(1)
        ns_match = re.search(r"-n\s+(\S+)", action_lower)
        namespace = ns_match.group(1) if ns_match else DEFAULT_NAMESPACE
        return ParsedOperation(OperationType.DELETE_POD, pod_name, namespace)

    # Pattern: 刪除 Pod <name> (Chinese delete)
    chinese_delete_match = re.search(r"刪除\s*[Pp]od\s+([a-z0-9][\w.-]*)", action)
    if chinese_delete_match:
        pod_name = chinese_delete_match.group(1)
        return ParsedOperation(OperationType.DELETE_POD, pod_name, DEFAULT_NAMESPACE)

    # Pattern: restart deployment <name> (English - with explicit "deployment")
    restart_deploy_match = re.search(
        r"restart\s+deployment[:\s]+([a-z0-9][\w.-]*)", action_lower
    )
    if restart_deploy_match:
        deploy_name = restart_deploy_match.group(1)
        ns_match = re.search(r"-n\s+(\S+)", action_lower)
        namespace = ns_match.group(1) if ns_match else DEFAULT_NAMESPACE
        return ParsedOperation(OperationType.RESTART_DEPLOYMENT, deploy_name, namespace)

    # Pattern: restart <name> (English - without "deployment" keyword)
    restart_simple_match = re.search(r"restart\s+([a-z0-9][\w.-]*)", action_lower)
    if restart_simple_match:
        deploy_name = restart_simple_match.group(1)
        # Skip if captured word is "deployment" (handled above)
        if deploy_name != "deployment":
            ns_match = re.search(r"-n\s+(\S+)", action_lower)
            namespace = ns_match.group(1) if ns_match else DEFAULT_NAMESPACE
            return ParsedOperation(
                OperationType.RESTART_DEPLOYMENT, deploy_name, namespace
            )

    # Pattern: 重新啟動 deployment <name> (Chinese with "deployment" keyword)
    chinese_restart_deploy_match = re.search(
        r"重新啟動\s+deployment\s+([a-z0-9][\w.-]*)", action, re.IGNORECASE
    )
    if chinese_restart_deploy_match:
        deploy_name = chinese_restart_deploy_match.group(1)
        return ParsedOperation(OperationType.RESTART_DEPLOYMENT, deploy_name, DEFAULT_NAMESPACE)

    # Pattern: 重新啟動 <name> 服務 (Chinese)
    chinese_restart_match = re.search(r"重新啟動\s+([a-z0-9][\w.-]*)\s*服務", action)
    if chinese_restart_match:
        resource_name = chinese_restart_match.group(1)
        # StatefulSet Pod 格式: name-N (如 postgres-primary-0)
        if re.match(r".*-\d+$", resource_name):
            return ParsedOperation(OperationType.DELETE_POD, resource_name, DEFAULT_NAMESPACE)
        return ParsedOperation(
            OperationType.RESTART_DEPLOYMENT, resource_name, DEFAULT_NAMESPACE
        )

    # Pattern: scale deployment <name>
    scale_match = re.search(
        r"scale\s+(?:deployment[:\s]+)?([a-z0-9][\w.-]*)", action_lower
    )
    if scale_match:
        deploy_name = scale_match.group(1)
        ns_match = re.search(r"-n\s+(\S+)", action_lower)
        namespace = ns_match.group(1) if ns_match else DEFAULT_NAMESPACE
        return ParsedOperation(OperationType.SCALE_DEPLOYMENT, deploy_name, namespace)

    # Pattern: 擴容 <name> (Chinese scale)
    chinese_scale_match = re.search(r"擴容\s+([a-z0-9][\w.-]*)", action)
    if chinese_scale_match:
        deploy_name = chinese_scale_match.group(1)
        return ParsedOperation(OperationType.SCALE_DEPLOYMENT, deploy_name, DEFAULT_NAMESPACE)

    # Pattern: 擴展 <name> 副本數 (Chinese scale variant)
    chinese_scale2_match = re.search(r"擴展\s+([a-z0-9][\w.-]*)\s*副本", action)
    if chinese_scale2_match:
        deploy_name = chinese_scale2_match.group(1)
        # 移除常見的後綴如 -deployment
        deploy_name = re.sub(r"-deployment$", "", deploy_name)
        return ParsedOperation(OperationType.SCALE_DEPLOYMENT, deploy_name, DEFAULT_NAMESPACE)

    # Pattern: 重新啟動 <name> (Chinese restart without 服務)
    chinese_restart2_match = re.search(r"重新啟動\s+([a-z0-9][\w.-]*)", action)
    if chinese_restart2_match:
        resource_name = chinese_restart2_match.group(1)
        # StatefulSet Pod 格式: name-N (如 postgres-primary-0)
        if re.match(r".*-\d+$", resource_name):
            return ParsedOperation(OperationType.DELETE_POD, resource_name, DEFAULT_NAMESPACE)
        # 移除常見的後綴
        deploy_name = re.sub(r"-deployment$", "", resource_name)
        return ParsedOperation(
            OperationType.RESTART_DEPLOYMENT, deploy_name, DEFAULT_NAMESPACE
        )

    return ParsedOperation(None, None, DEFAULT_NAMESPACE)
