# -*- coding: utf-8 -*-
"""
thresholds.py — 阈值表与状态判定

移植参考脚本 Get-Threshold / Get-StatusByValue 的核心子集部分。

状态判定优先级（与 parser._resolve_status 配合）：
  1. 模块自带的 *_LEVEL 字段（最权威）
  2. 值文本状态词映射
  3. 本模块阈值规则数值判定
"""

from __future__ import annotations

import re
from typing import Dict, Optional

# ============================================================
# 阈值表：KEY → 阈值描述（参考脚本 Get-Threshold）
# 只包含本期核心子集涉及的 KEY
# ============================================================
THRESHOLDS: Dict[str, str] = {
    # ---- 系统基础 ----
    "LOAD_1MIN": ">8",
    "LOAD_5MIN": ">8",
    "LOAD_15MIN": ">8",

    # ---- CPU ----
    "CPU_USAGE": ">85%",
    "CPU_PER_CORE": ">85%",
    "CPU_CONTEXT_SWITCHES": ">10000",

    # ---- 内存 ----
    "MEMORY_USAGE": ">85%",
    "SWAP_USAGE": ">20%",
    "MEMORY_PRESSURE_AVG10": ">10",
    "MEMORY_PRESSURE_AVG60": ">10",

    # ---- 磁盘 ----
    "DISK_USAGE": ">90%",
    "DISK_LATENCY": ">100ms",

    # ---- MySQL ----
    "MYSQL_CONNECTIONS_USAGE": ">80%",
    "MYSQL_SLOW_QUERIES": ">100",
    "MYSQL_SLAVE_DELAY": ">10s",
    "MYSQL_INNODB_HIT_RATE": "<95%",
    "MYSQL_OPEN_TABLES": ">1000",

    # ---- Redis ----
    "REDIS_KEYS": ">1000000",
    "REDIS_MEM_FRAGMENTATION": ">5",
    "REDIS_CLIENTS": ">500",
    "REDIS_CLIENTS_USAGE": ">80%",
    "REDIS_HIT_RATE": "<90%",
    "REDIS_MEMORY_USAGE": ">80%",
    "REDIS_BLOCKED_CLIENTS": ">10",
    "REDIS_SLAVES": "<1",

    # ---- MySQL深度 ----
    "MYSQL_DEPTH_CONNECTION_USAGE": ">80%",
    "MYSQL_DEPTH_SLOW_QUERY_COUNT": ">100",
    "MYSQL_DEPTH_BUFFER_POOL_HIT_RATE": "<95%",
    "MYSQL_DEPTH_SLAVE_DELAY": ">10s",
    "MYSQL_DEPTH_DEADLOCKS": ">0",
    "MYSQL_DEPTH_LOCK_WAITS": ">0",
    "MYSQL_DEPTH_FRAGMENTED_TABLES": ">10",

    # ---- Redis深度 ----
    "REDIS_DEPTH_MEM_FRAGMENTATION": ">5",
    "REDIS_DEPTH_CACHE_HIT_RATE": "<90%",
    "REDIS_DEPTH_BLOCKED_CLIENTS": ">10",
    "REDIS_DEPTH_REJECTED_CONNECTIONS": ">0",
    "REDIS_DEPTH_SLOWLOG_COUNT": ">10",

    # ---- 安全合规深度检测 ----
    "SECURITY_DEEP_MYSQL_EMPTY_PWD_USERS": ">0",
    "SECURITY_DEEP_LINUX_EMPTY_PWD_COUNT": ">0",
    "SECURITY_DEEP_SUSPICIOUS_SUID_COUNT": ">0",
    "SECURITY_DEEP_SUSPICIOUS_CRON_COUNT": ">0",
    "SECURITY_DEEP_SSH_BRUTEFORCE_IPS": ">0",
    "SECURITY_DEEP_UNEXPECTED_PORTS_COUNT": ">0",
}


# ============================================================
# 解析器
# ============================================================

_NUM_RE = re.compile(r"([<>]?)(=?)\s*([\d.]+)([%\w]*)$")


def _parse_threshold(raw: str):
    """解析阈值文本，返回 (op, value_str, unit)。

    如 ">85%" → (">", "85", "%")
       "<95%" → ("<", "95", "%")
       ">8"   → (">", "8", "")
       ">1000000" → (">", "1000000", "")
    """
    m = _NUM_RE.match(raw.strip())
    if not m:
        return None
    op = m.group(1) or ""
    eq = m.group(2) or ""
    val = m.group(3)
    unit = m.group(4) or ""
    return (op + eq, val, unit)


def _extract_numeric(value: str):
    """从值字符串中提取数值。

    如 "85.3%" → 85.3, "%"
       "3.69"  → 3.69, ""
       "10s"   → 10, "s"
       "500MB" → 500, "MB"
    """
    m = re.match(r"([\d.]+)\s*(%|s|ms|MB|GB|TB|天|天)?", value.strip())
    if not m:
        return None, value
    return float(m.group(1)), m.group(2) or ""


def _compare(value_num, op, threshold_num):
    """执行数值比较。"""
    if op.startswith(">"):
        eq = "=" in op
        return value_num >= threshold_num if eq else value_num > threshold_num
    if op.startswith("<"):
        eq = "=" in op
        return value_num <= threshold_num if eq else value_num < threshold_num
    # 无操作符，精确匹配
    return abs(value_num - threshold_num) < 0.001


def judge_status(key: str, value: str, threshold: str) -> Optional[str]:
    """按阈值规则判定状态。

    Args:
        key: 检测项 KEY，如 "CPU_USAGE"
        value: 实际值字符串，如 "85.3%"
        threshold: 阈值描述，如 ">85%"

    Returns:
        "警告" / "严重" 或 None（正常或无法判定）
    """
    parsed = _parse_threshold(threshold)
    if not parsed:
        return None

    op, t_val_str, t_unit = parsed
    t_val = float(t_val_str)
    v_num, v_unit = _extract_numeric(value)

    if v_num is None:
        # 值无法提取数值（如 "未知"、"获取失败"），正常
        return None

    # 单位不匹配跳过（如阈值 "%" 值 "MB"），不判定
    if t_unit and v_unit and t_unit != v_unit:
        return None

    if _compare(v_num, op, t_val):
        # 严重/警告拆分：严重用双倍阈值或 +10%
        if op.startswith(">"):
            # >85%: 超过阈值是警告，超过阈值×1.1 或固定加 10 是严重
            severe_threshold = t_val * 1.1 if t_unit in ("%", "") else t_val * 2
            if _compare(v_num, ">", severe_threshold):
                return "严重"
            return "警告"
        elif op.startswith("<"):
            # <95%: 低于阈值是警告，低于 90% 是严重
            severe_threshold = t_val * 0.9 if t_unit in ("%", "") else t_val * 0.5
            if _compare(v_num, "<", severe_threshold):
                return "严重"
            return "警告"

    return None
