namespace SHH.CameraSdk;

/// <summary>
/// [决策引擎] 故障自愈策略 (V3.3.1 修复版)
/// 核心职责：根据设备错误码特征，智能裁决系统应采取的恢复动作，实现故障自动化处理
/// 关键修复（Bug R）：
/// <para>1. 致命错误防护：对 InvalidCredentials/AccountLocked 等错误禁止重试，防止账号被锁、IP 拉黑</para>
/// <para>2. 未知错误保守策略：对 Unknown 错误采用 ManualIntervention，避免未知风险扩散</para>
/// 设计原则：最小化风险、最大化自愈率，区分可重试/不可重试/需人工干预的错误类型
/// </summary>
public static class RecoveryPolicy
{
    #region --- 1. 核心决策逻辑：错误码→自愈动作映射 ---

    /// <summary>
    /// 根据相机错误码判定对应的故障自愈动作
    /// </summary>
    /// <param name="code">设备上报的错误码</param>
    /// <returns>标准化的自愈动作指令</returns>
    public static RecoveryAction GetAction(CameraErrorCode code)
    {
        return code switch
        {
            // ========== 场景 A: 网络类故障 (可自愈) ==========
            // 策略：指数退避重试
            // 理由：网络波动、超时、闪断为暂时性故障，延迟重试大概率恢复
            CameraErrorCode.NetworkUnreachable or
            CameraErrorCode.NetworkSendError or
            CameraErrorCode.NetworkRecvError or
            CameraErrorCode.Timeout or
            CameraErrorCode.SocketError or
            CameraErrorCode.StreamInterrupted or
            CameraErrorCode.DeviceRebooting => RecoveryAction.RetryWithBackoff,

            // ========== 场景 B: 资源繁忙类故障 (可自愈) ==========
            // 策略：指数退避重试
            // 理由：设备连接数满、缓冲区溢出，等待资源释放后可恢复
            CameraErrorCode.DeviceResourceBusy or
            CameraErrorCode.DeviceBufferOverflow or
            CameraErrorCode.DeviceBusy or
            CameraErrorCode.OperationNotFinished or
            CameraErrorCode.PortPoolExhausted or
            CameraErrorCode.MaxConnectionsReached or
            CameraErrorCode.MaxStreamExceeded => RecoveryAction.RetryWithBackoff,

            // ========== 场景 C: 致命错误 (不可自愈，禁止重试) ==========
            // 策略：立即停止
            // 理由：密码错误、账号锁定、组件缺失等故障，重试无意义且会加剧风险（账号锁死、日志爆炸）
            CameraErrorCode.InvalidCredentials or
            CameraErrorCode.AccessDenied or
            CameraErrorCode.UserNotExist or
            CameraErrorCode.AccountLocked or
            CameraErrorCode.SessionExpired or
            CameraErrorCode.InvalidChannel or
            CameraErrorCode.IpConflict or
            CameraErrorCode.SdkNotInitialized or
            CameraErrorCode.ComponentLoadFailed or
            CameraErrorCode.EncryptionLibError => RecoveryAction.FatalStop,

            // ========== 场景 D: 硬件故障 (需人工干预) ==========
            // 策略：人工介入
            // 理由：硬盘损坏、存储满等故障属于硬件层面，软件无法修复
            CameraErrorCode.HardwareFault or
            CameraErrorCode.StorageError or
            CameraErrorCode.DiskFull or
            CameraErrorCode.DiskReadOnly => RecoveryAction.ManualIntervention,

            // ========== 场景 E: 正常状态 ==========
            CameraErrorCode.Success => RecoveryAction.None,

            // ========== 场景 F: 未知错误 (关键修复 Bug R) ==========
            // 旧策略：盲目重试 → 新策略：人工干预
            // 理由：未知错误可能包含 IP 拉黑、协议不兼容等严重问题，重试会扩大风险
            _ => RecoveryAction.ManualIntervention
        };
    }

    #endregion

    #region --- 2. 辅助算法：指数退避延迟计算 ---

    /// <summary>
    /// 获取建议的指数退避延迟时间（毫秒）
    /// 算法公式：delay = min(2^n * 1000, 120000)，n = 当前重试次数
    /// 限流规则：第一次 2s → 第二次 4s → ... → 第六次 64s → 上限 120s（2分钟）
    /// </summary>
    /// <param name="retryCount">当前重试次数（从 1 开始计数）</param>
    /// <returns>延迟毫秒数</returns>
    public static int GetRetryDelay(int retryCount)
    {
        // 限制重试次数最大为 7，防止指数爆炸导致数值溢出
        int exponent = Math.Min(retryCount, 7);
        // 计算指数退避秒数
        int delaySeconds = (int)Math.Pow(2, exponent);
        // 转换为毫秒并限制上限为 2 分钟（120000ms）
        return Math.Min(delaySeconds * 1000, 120000);
    }

    #endregion
}