/*
 * event_queue.c
 *
 *  Created on: 2026-03-04
 *      Author: RT-Thread
 *
 *  功能: 事件队列模块实现
 *  依赖: RT-Thread Nano, osal
 *  跨平台适配: 基于RT-Thread Nano，使用标准API
 */

#include <rtthread.h>
#include "osal.h"
#include "event_queue.h"

/* 事件队列结构 */
static event_queue_t g_event_queue;

/**
 * @brief 初始化事件队列
 * @return 0 成功，非0 失败
 */
int event_queue_init(void)
{
    /* 初始化事件队列 */
    g_event_queue.head = 0;
    g_event_queue.tail = 0;
    g_event_queue.count = 0;
    
    /* 初始化互斥锁 */
    g_event_queue.mutex = osal_mutex_create("event_mutex");
    if (g_event_queue.mutex == NULL)
    {
        osal_log_e("Failed to create event queue mutex");
        return -1;
    }
    
    /* 初始化信号量 */
    g_event_queue.sem = osal_sem_create("event_sem", 0);
    if (g_event_queue.sem == NULL)
    {
        osal_log_e("Failed to create event queue semaphore");
        osal_mutex_delete(g_event_queue.mutex);
        return -1;
    }
    
    osal_log_i("Event queue initialized");
    return 0;
}

/**
 * @brief 销毁事件队列
 * @return 0 成功，非0 失败
 */
int event_queue_deinit(void)
{
    if (g_event_queue.mutex != NULL)
    {
        osal_mutex_delete(g_event_queue.mutex);
        g_event_queue.mutex = NULL;
    }
    
    if (g_event_queue.sem != NULL)
    {
        osal_sem_delete(g_event_queue.sem);
        g_event_queue.sem = NULL;
    }
    
    osal_log_i("Event queue deinitialized");
    return 0;
}

/**
 * @brief 向事件队列中添加事件
 * @param event 事件指针
 * @return 0 成功，非0 失败
 */
int event_queue_push(event_t *event)
{
    if (event == NULL)
    {
        return -1;
    }
    
    /* 加锁 */
    if (osal_mutex_take(g_event_queue.mutex, OSAL_WAIT_FOREVER) != OSAL_OK)
    {
        osal_log_e("Failed to take event queue mutex");
        return -1;
    }
    
    /* 检查队列是否已满 */
    if (g_event_queue.count >= EVENT_QUEUE_SIZE)
    {
        osal_log_w("Event queue is full, dropping event");
        osal_mutex_release(g_event_queue.mutex);
        return -1;
    }
    
    /* 添加事件到队列 */
    g_event_queue.events[g_event_queue.tail] = *event;
    g_event_queue.tail = (g_event_queue.tail + 1) % EVENT_QUEUE_SIZE;
    g_event_queue.count++;
    
    /* 解锁 */
    osal_mutex_release(g_event_queue.mutex);
    
    /* 释放信号量 */
    osal_sem_release(g_event_queue.sem);
    
    return 0;
}

/**
 * @brief 从事件队列中获取事件
 * @param event 事件指针，用于存储获取的事件
 * @param timeout 超时时间，单位ms
 * @return 0 成功，非0 失败
 */
int event_queue_pop(event_t *event, int timeout)
{
    if (event == NULL)
    {
        return -1;
    }
    
    /* 等待信号量 */
    if (osal_sem_take(g_event_queue.sem, timeout) != OSAL_OK)
    {
        return -1;
    }
    
    /* 加锁 */
    if (osal_mutex_take(g_event_queue.mutex, OSAL_WAIT_FOREVER) != OSAL_OK)
    {
        osal_log_e("Failed to take event queue mutex");
        return -1;
    }
    
    /* 检查队列是否为空 */
    if (g_event_queue.count == 0)
    {
        osal_mutex_release(g_event_queue.mutex);
        return -1;
    }
    
    /* 从队列中获取事件 */
    *event = g_event_queue.events[g_event_queue.head];
    g_event_queue.head = (g_event_queue.head + 1) % EVENT_QUEUE_SIZE;
    g_event_queue.count--;
    
    /* 解锁 */
    osal_mutex_release(g_event_queue.mutex);
    
    return 0;
}

/**
 * @brief 获取事件队列中的事件数量
 * @return 事件数量
 */
int event_queue_get_count(void)
{
    int count;
    
    /* 加锁 */
    if (osal_mutex_take(g_event_queue.mutex, OSAL_WAIT_FOREVER) != OSAL_OK)
    {
        osal_log_e("Failed to take event queue mutex");
        return -1;
    }
    
    count = g_event_queue.count;
    
    /* 解锁 */
    osal_mutex_release(g_event_queue.mutex);
    
    return count;
}

/**
 * @brief 清空事件队列
 * @return 0 成功，非0 失败
 */
int event_queue_clear(void)
{
    /* 加锁 */
    if (osal_mutex_take(g_event_queue.mutex, OSAL_WAIT_FOREVER) != OSAL_OK)
    {
        osal_log_e("Failed to take event queue mutex");
        return -1;
    }
    
    /* 清空队列 */
    g_event_queue.head = 0;
    g_event_queue.tail = 0;
    g_event_queue.count = 0;
    
    /* 解锁 */
    osal_mutex_release(g_event_queue.mutex);
    
    return 0;
}
