namespace SHH.CameraSdk;

/// <summary>
/// 全局遥测仓储（静态类）
/// 功能：存储并提供帧生命周期的追踪日志查询，采用环形缓冲区机制限制日志数量
/// 用途：用于问题排查、性能分析，记录每帧的处理流程、耗时、丢弃原因等信息
/// </summary>
public static class GlobalTelemetry
{
    #region --- 静态存储资源 (Static Storage Resources) ---

    /// <summary>
    /// 环形日志缓冲区：存储帧追踪上下文（线程安全）
    /// Key：帧序列号（FrameSequence），Value：帧全链路追踪上下文
    /// </summary>
    private static readonly ConcurrentDictionary<long, FrameContext> _logs = new();

    /// <summary>
    /// 日志序列号队列：用于维护环形缓冲区的淘汰顺序（线程安全）
    /// 作用：记录帧日志的插入顺序，超过最大数量时淘汰最早的记录
    /// </summary>
    private static readonly ConcurrentQueue<long> _keys = new();

    /// <summary>
    /// 最大日志保留数量：限制环形缓冲区仅保留最近 200 条帧追踪记录
    /// 目的：防止日志过多导致内存占用飙升
    /// </summary>
    private const int MaxLogCount = 200;

    #endregion

    #region --- 核心操作方法 (Core Operation Methods) ---

    /// <summary>
    /// 记录帧追踪日志
    /// 功能：将帧上下文存入缓冲区，超过最大数量时自动淘汰最早的记录
    /// </summary>
    /// <param name="frameSeq">帧序列号（唯一标识某一帧）</param>
    /// <param name="context">帧全链路追踪上下文（含处理日志、耗时、丢弃原因等）</param>
    public static void RecordLog(long frameSeq, FrameContext context)
    {
        // 存入日志缓冲区（存在相同序列号时会覆盖，确保最新记录）
        _logs[frameSeq] = context;
        // 记录序列号到队列，用于后续淘汰逻辑
        _keys.Enqueue(frameSeq);

        // 环形缓冲区淘汰逻辑：超过最大数量时，移除最早插入的记录
        if (_keys.Count > MaxLogCount && _keys.TryDequeue(out var oldKey))
        {
            _logs.TryRemove(oldKey, out _);
        }
    }

    /// <summary>
    /// 获取最近的帧追踪日志
    /// 功能：按时间戳降序返回缓冲区中的所有记录（最新记录在前）
    /// </summary>
    /// <returns>帧追踪上下文集合（最多 MaxLogCount 条）</returns>
    public static IEnumerable<FrameContext> GetRecentLogs()
    {
        // 按帧上下文的时间戳降序排序，确保最新记录优先返回
        return _logs.Values.OrderByDescending(x => x.Timestamp);
    }

    #endregion
}