using Serilog;
namespace SHH.CameraSdk;
///
/// [架构基类] 工业级视频源抽象核心 (V3.5.0 严格匹配版)
/// 当前模块: AiVideo | 核心原则: 低耦合、高并发、零拷贝
/// 核心职责:
/// 1. 生命周期管理:基于 实现 Start/Stop/UpdateConfig 的线程安全串行化
/// 2. 状态分发系统:利用 (DropOldest策略) 实现高性能、非阻塞的状态变更通知
/// 3. 遥测统计引擎:内置原子级 FPS 计算与 Mbps 带宽监控,支持网络层与解码层双路流量计费
/// 4. 弹性自愈机制:集成 IsAuthFailed 冻结期与物理网络 (Ping) 状态同步,支持 Coordinator 级自动重连
/// 5. 审计与追踪:内置环形审计日志 (Max:100),记录配置变更、动态参数应用及驱动层异常
/// 关键修复记录:
/// ✅ [V3.3.5] 资源防御:在 DisposeAsync 中强化生命周期锁,防止销毁期间触发重入
/// ✅ [V3.3.5] 自愈增强:引入 Environment.TickCount64 宽限期机制,解决启动瞬间心跳超时误判
/// ✅ [Bug A] 死锁免疫:强制所有 await 添加 ConfigureAwait(false),彻底解除对同步上下文的依赖
/// ✅ [Bug π] 管道安全:Dispose 采用 TryComplete 优雅关闭策略,确保缓冲区剩余状态消息被完全消费
///
public abstract class BaseVideoSource : IVideoSource, IAsyncDisposable, IDeviceConnectivity
{
#region --- 1. 核心字段与锁机制 (Fields & Locks) ---
///
/// 核心配置对象(支持热更新)
/// 注意:外部修改需通过 UpdateConfig 方法,确保线程安全
///
protected VideoSourceConfig _config;
/// 状态同步锁:保护 _status 字段的读写原子性,防止多线程竞争导致状态不一致
private readonly object _stateSyncRoot = new();
///
/// 生命周期互斥锁(信号量)
/// 作用:确保 StartAsync/StopAsync/UpdateConfig 串行执行,防止重入导致状态机混乱
/// 配置:初始计数 1,最大计数 1 → 互斥锁
///
private readonly SemaphoreSlim _lifecycleLock = new(1, 1);
/// 跟踪上一个未完成的生命周期任务
private Task _pendingLifecycleTask = Task.CompletedTask;
/// 物理在线状态(由哨兵 Ping 更新)
private volatile bool _isPhysicalOnline;
/// 设备在线状态标志(volatile 确保多线程可见性)
private volatile bool _isActived;
/// 视频源核心状态(受 _stateSyncRoot 保护)
private VideoSourceStatus _status = VideoSourceStatus.Disconnected;
/// 资源销毁标记
private volatile bool _isDisposed = false;
#endregion
#region --- 2. 状态分发基础设施 (Status Channel) ---
///
/// 状态通知有界通道
/// 特性:DropOldest 策略,消费者过载时丢弃旧状态,防止内存溢出
/// 配置:容量 100 | 单读者多写者
///
private readonly Channel _statusQueue;
/// 状态分发器的取消令牌源
private CancellationTokenSource? _distributorCts;
/// 状态分发任务引用(用于 Dispose 时优雅等待)
private Task? _distributorTask;
#endregion
#region --- 3. 遥测与性能统计 (Telemetry & Stats) ---
/// 最后一帧接收的系统 Tick(单调时钟,不受系统时间修改影响)
private long _lastFrameTick = 0;
/// 生命周期内接收的总帧数
private long _totalFramesReceived = 0;
/// FPS 计算临时计数器
private int _tempFrameCounter = 0;
/// 上次 FPS 计算的 Tick 时间
private long _lastFpsCalcTick = 0;
/// 实时码率 (Mbps)
protected double _currentBitrate = 0;
/// 码率计算临时字节计数器
private long _tempByteCounter = 0;
#endregion
#region --- 4. 审计日志与自愈标记 (Audit & Resilience) ---
/// 审计日志列表(线程安全访问)
private readonly List _auditLogs = new();
/// 最大日志条数(滚动清除,防止内存溢出)
private const int MaxAuditLogCount = 100;
///
/// 认证类致命错误标记(如密码错、用户锁定)
/// 作用:触发 15 分钟长冷冻期,防止 IP 被相机锁定
///
public bool IsAuthFailed { get; set; }
/// 上次尝试执行 StartAsync 的系统 Tick 时间 (单调时钟)
private long _lastStartAttemptTick = 0;
#endregion
#region --- 5. 公开事件 (Events) ---
/// 视频帧回调事件(热路径,低延迟分发)
public event Action