/** @file dc_event.cpp — 事件队列（SOE/扰动/故障） */
#include "dc_internal.h"
#include <queue>

#define EVENT_QUEUE_MAX_SIZE  1024     /**< 每种事件队列最大容量, 超出则丢弃最旧 */

static std::mutex                g_soe_mutex;
static std::queue<void *>        g_soe_queue;
static std::vector<dc_queue_pop_cb_t> g_soe_cbs;

static std::mutex                g_dist_mutex;
static std::queue<void *>        g_dist_queue;
static std::vector<dc_queue_pop_cb_t> g_dist_cbs;

static std::mutex                g_fault_mutex;
static std::queue<void *>        g_fault_queue;
static std::vector<dc_queue_pop_cb_t> g_fault_cbs;

/** @brief 事件队列弹出内部实现：swap 交换后遍历回调 */
static void dc_event_pop_inner(std::mutex &mtx, std::queue<void *> &q,
    std::vector<dc_queue_pop_cb_t> &cbs)
{
    std::queue<void *> lq;
    std::vector<dc_queue_pop_cb_t> lcbs;

    {
        std::lock_guard<std::mutex> lk(mtx);
        lq.swap(q);
        lcbs = cbs;
    }

    while (!lq.empty())
    {
        void *p = lq.front();
        lq.pop();
        for (auto &cb : lcbs)
        {
            cb(p);
        }
    }
}

/* ================================================================
 * SOE 事件队列
 * ================================================================ */

/** @brief 向 SOE 事件队列推送数据 (超过上限丢弃最旧) */
int dc_event_queue_push(void *p)
{
    if (!p)
    {
        return DC_ERR_PARAM;
    }

    std::lock_guard<std::mutex> lk(g_soe_mutex);

    if (g_soe_queue.size() >= EVENT_QUEUE_MAX_SIZE)
    {
        LOG_E("dc_event_queue_push: queue full (%zu), dropping oldest",
            g_soe_queue.size());
        void *old = g_soe_queue.front();
        g_soe_queue.pop();
        dc_util_destroy_data(old, DATA_TYPE_U8); /* SOE 事件内存释放 */
    }

    g_soe_queue.push(p);

    return DC_OK;
}

/** @brief 注册 SOE 事件队列弹出回调 */
int dc_event_register_queue_pop(dc_queue_pop_cb_t cb)
{
    if (!cb)
    {
        return DC_ERR_PARAM;
    }

    std::lock_guard<std::mutex> lk(g_soe_mutex);
    g_soe_cbs.push_back(cb);

    return DC_OK;
}

/** @brief 触发 SOE 事件队列弹出 */
void dc_event_queue_pop(void)
{
    dc_event_pop_inner(g_soe_mutex, g_soe_queue, g_soe_cbs);
}

/* ================================================================
 * 扰动录波事件队列
 * ================================================================ */

/** @brief 向扰动事件队列推送数据 (超过上限丢弃最旧) */
int dc_disturb_dd_queue_push(void *p)
{
	if (!p)
	{
		return DC_ERR_PARAM;
	}

	std::lock_guard<std::mutex> lk(g_dist_mutex);

	if (g_dist_queue.size() >= EVENT_QUEUE_MAX_SIZE)
	{
		LOG_E("dc_disturb_dd_queue_push: queue full (%zu), dropping oldest",
			g_dist_queue.size());
		void *old = g_dist_queue.front();
		g_dist_queue.pop();
		dc_util_destroy_data(old, DATA_TYPE_U8);
	}

	g_dist_queue.push(p);

	return DC_OK;
}

/** @brief 注册扰动事件队列弹出回调 */
int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb_t cb)
{
    if (!cb)
    {
        return DC_ERR_PARAM;
    }

    std::lock_guard<std::mutex> lk(g_dist_mutex);
    g_dist_cbs.push_back(cb);

    return DC_OK;
}

/** @brief 触发扰动事件队列弹出 */
void dc_disturb_dd_queue_pop(void)
{
    dc_event_pop_inner(g_dist_mutex, g_dist_queue, g_dist_cbs);
}

/* ================================================================
 * 故障事件队列
 * ================================================================ */

/** @brief 向故障事件队列推送数据 (超过上限丢弃最旧) */
int dc_fault_queue_push(void *p)
{
	if (!p)
	{
		return DC_ERR_PARAM;
	}

	std::lock_guard<std::mutex> lk(g_fault_mutex);

	if (g_fault_queue.size() >= EVENT_QUEUE_MAX_SIZE)
	{
		LOG_E("dc_fault_queue_push: queue full (%zu), dropping oldest",
			g_fault_queue.size());
		void *old = g_fault_queue.front();
		g_fault_queue.pop();
		dc_util_destroy_data(old, DATA_TYPE_U8);
	}

	g_fault_queue.push(p);

	return DC_OK;
}

/** @brief 注册故障事件队列弹出回调 */
int dc_fault_register_queue_pop(dc_queue_pop_cb_t cb)
{
    if (!cb)
    {
        return DC_ERR_PARAM;
    }

    std::lock_guard<std::mutex> lk(g_fault_mutex);
    g_fault_cbs.push_back(cb);

    return DC_OK;
}

/** @brief 触发故障事件队列弹出 */
void dc_fault_queue_pop(void)
{
    dc_event_pop_inner(g_fault_mutex, g_fault_queue, g_fault_cbs);
}
