/**
 * @file    myTask.h
 * @brief   任务框架接口 — 定时器 + 事件 + 消息队列（C 接口）
 * @details 基于 SPEC §8 原工程分析。
 *          定时器基于 timerfd + epoll 实现，精确到毫秒。
 *          事件基于位图 + pthread 条件变量实现。
 *          消息队列基于环形缓冲区 + 互斥锁 + 条件变量实现。
 */

#ifndef _MY_TASK_H_
#define _MY_TASK_H_

#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

/* ================================================================
 * 通用定义
 * ================================================================ */

/** 定时器回调函数类型 */
typedef void (*timer_func_cb)(void *arg);

/** 不透明句柄类型 */
typedef void *stru_task_timer_t;
typedef void *stru_task_event_t;
typedef void *stru_task_msg_queue_t;

/* ================================================================
 * 定时器标志
 * ================================================================ */

/** 单次触发（到期后自动停止） */
#define TASK_TIMER_FLAG_ONCE     0x01

/** 周期触发（到期后自动重新计时） */
#define TASK_TIMER_FLAG_PERIODIC 0x02

/* ================================================================
 * 事件等待方式
 * ================================================================ */

/** 永久等待（不超时） */
#define TASK_EVENT_WAIT_FOREVER  0xFFFFFFFF

/** 事件标记：等待所有位都置位（AND 模式） */
#define TASK_EVENT_FLAG_AND      0x01

/** 事件标记：等待任意位置位（OR 模式） */
#define TASK_EVENT_FLAG_OR       0x02

/** 事件标记：接收后自动清除已匹配的位 */
#define TASK_EVENT_FLAG_CLEAR    0x04

/* ================================================================
 * 通用延时
 * ================================================================ */

/**
 * @brief  任务延时（毫秒级阻塞等待）
 * @param  ms  延时毫秒数
 */
void task_sleep_ms(uint32_t ms);

/* ================================================================
 * 事件 API
 * ================================================================ */

/**
 * @brief  创建事件对象
 * @param  name  事件名称（调试用）
 * @return 事件句柄，失败返回 NULL
 */
stru_task_event_t task_event_create(const char *name);

/**
 * @brief  销毁事件对象
 * @param  p_event  事件句柄
 * @return 0 成功，-1 失败
 */
int task_event_destroy(stru_task_event_t p_event);

/**
 * @brief  发送事件（设置事件位）
 * @param  p_event  事件句柄
 * @param  event    要设置的事件位掩码
 * @return 0 成功，-1 失败
 */
int task_event_send(stru_task_event_t p_event, uint32_t event);

/**
 * @brief  等待事件
 * @param  p_event     事件句柄
 * @param  set         期望的事件位掩码
 * @param  opt         等待选项（TASK_EVENT_FLAG_AND/OR/CLEAR 组合）
 * @param  timeout_ms  超时时间（毫秒，TASK_EVENT_WAIT_FOREVER=永久等待）
 * @param  recved      输出参数：实际收到的事件位
 * @return 0 成功，-1 超时或失败
 */
int task_event_recv(stru_task_event_t p_event, uint32_t set, uint32_t opt,
                    uint32_t timeout_ms, uint32_t *recved);

/**
 * @brief  清除事件位
 * @param  p_event  事件句柄
 * @param  event    要清除的事件位掩码
 * @return 0 成功，-1 失败
 */
int task_event_clear(stru_task_event_t p_event, uint32_t event);

/**
 * @brief  查询当前事件位（非阻塞）
 * @param  p_event  事件句柄
 * @return 当前事件位掩码
 */
uint32_t task_event_query(stru_task_event_t p_event);

/* ================================================================
 * 消息队列 API
 * ================================================================ */

/**
 * @brief  创建定长消息队列
 * @param  name      队列名称（调试用）
 * @param  msg_size  每条消息的最大字节数
 * @param  msg_num   队列容量（最大消息条数）
 * @return 队列句柄，失败返回 NULL
 */
stru_task_msg_queue_t task_msg_queue_create(const char *name,
                                            uint32_t msg_size, uint32_t msg_num);

/**
 * @brief  销毁消息队列
 * @param  p_queue  队列句柄
 * @return 0 成功，-1 失败
 */
int task_msg_queue_destroy(stru_task_msg_queue_t p_queue);

/**
 * @brief  发送消息（队列满时阻塞等待）
 * @param  p_queue  队列句柄
 * @param  msg      消息内容指针
 * @param  size     消息实际字节数（<= msg_size）
 * @return 0 成功，-1 失败
 */
int task_msg_queue_send(stru_task_msg_queue_t p_queue, const void *msg,
                        uint32_t size);

/**
 * @brief  发送消息（带超时）
 * @param  timeout_ms  超时时间（毫秒，TASK_EVENT_WAIT_FOREVER=永久等待）
 * @return 0 成功，-1 超时或失败
 */
int task_msg_queue_send_timeout(stru_task_msg_queue_t p_queue, const void *msg,
                                uint32_t size, uint32_t timeout_ms);

/**
 * @brief  接收消息（带超时）
 * @param  timeout_ms  超时时间（毫秒，TASK_EVENT_WAIT_FOREVER=永久等待）
 * @return 0 成功，-1 超时或失败
 */
int task_msg_queue_recv(stru_task_msg_queue_t p_queue, void *msg,
                        uint32_t size, uint32_t timeout_ms);

/**
 * @brief  尝试接收消息（非阻塞，队列空立即返回 -1）
 * @return 0 成功，-1 队列空
 */
int task_msg_queue_try_recv(stru_task_msg_queue_t p_queue, void *msg,
                            uint32_t size);

/**
 * @brief  获取队列中当前消息数
 */
uint32_t task_msg_queue_get_count(stru_task_msg_queue_t p_queue);

/**
 * @brief  获取队列剩余可用空间（条数）
 */
uint32_t task_msg_queue_space(stru_task_msg_queue_t p_queue);

/* ================================================================
 * 定时器 API
 * ================================================================ */

/**
 * @brief  创建定时器（创建后不会自动启动，需调用 task_timer_start）
 * @param  name        定时器名称（调试用）
 * @param  fun_cb      到期回调函数
 * @param  arg         回调参数
 * @param  timeout_ms  定时周期（毫秒）
 * @param  flags       标志位（TASK_TIMER_FLAG_ONCE 或 TASK_TIMER_FLAG_PERIODIC）
 * @return 定时器句柄，失败返回 NULL
 */
stru_task_timer_t task_timer_create(const char *name, timer_func_cb fun_cb,
                                    void *arg, uint32_t timeout_ms, int flags);

/**
 * @brief  启动定时器
 * @return 0 成功，-1 失败
 */
int task_timer_start(stru_task_timer_t p_timer);

/**
 * @brief  停止定时器
 * @return 0 成功，-1 失败
 */
int task_timer_stop(stru_task_timer_t p_timer);

/**
 * @brief  重启定时器（可修改周期）
 * @param  timeout_ms  新的定时周期（毫秒）
 * @return 0 成功，-1 失败
 */
int task_timer_restart(stru_task_timer_t p_timer, uint32_t timeout_ms);

/**
 * @brief  销毁定时器
 * @return 0 成功，-1 失败
 */
int task_timer_destroy(stru_task_timer_t p_timer);

/**
 * @brief  查询定时器是否在运行
 * @return 1=运行中，0=已停止
 */
int task_timer_is_active(stru_task_timer_t p_timer);

#ifdef __cplusplus
}
#endif

#endif /* _MY_TASK_H_ */
