/*
 * 模块名称：Network Select API
 * 模块功能：I/O 多路复用接口，支持 select 和 poll 模式，
 *          用于同时监控多个 Socket 的读写事件
 * 适用平台：STM32F4 系列（CH395F 以太网芯片）
 * 作者：王建锋
 * 创建日期：2026-07-18
 * 修改记录：
 */

#ifndef __NET_SELECT_H
#define __NET_SELECT_H

#ifdef __cplusplus
extern "C" {
#endif

#include "net_types.h"
#include "net_config.h"

/*
 * 文件描述符集合
 * 每个位对应一个 socket 描述符 (0~7)
 */
typedef struct {
    uint32_t fd_bits;                   /* 位掩码 */
} net_fd_set;

/*
 * 时间结构体
 */
typedef struct {
    long tv_sec;                        /* 秒 */
    long tv_usec;                       /* 微秒 */
} net_timeval;

/*
 * poll 事件结构体
 */
typedef struct {
    int fd;                             /* socket 描述符 */
    short events;                       /* 请求的事件 */
    short revents;                      /* 实际发生的事件 */
} net_pollfd;

/*
 * poll 事件掩码
 */
#define NET_POLLIN          0x0001      /* 可读 */
#define NET_POLLOUT         0x0004      /* 可写 */
#define NET_POLLERR         0x0008      /* 错误 */
#define NET_POLLHUP         0x0010      /* 挂起 */
#define NET_POLLNVAL        0x0020      /* 无效请求 */

/*
 * fd_set 操作宏
 */

/*
 * 函数功能：清空 fd_set
 */
#define NET_FD_ZERO(fdset) ((fdset)->fd_bits = 0)

/*
 * 函数功能：将 fd 加入 fd_set
 */
#define NET_FD_SET(fd, fdset) ((fdset)->fd_bits |= (1U << (fd)))

/*
 * 函数功能：将 fd 从 fd_set 移除
 */
#define NET_FD_CLR(fd, fdset) ((fdset)->fd_bits &= ~(1U << (fd)))

/*
 * 函数功能：检查 fd 是否在 fd_set 中
 */
#define NET_FD_ISSET(fd, fdset) (((fdset)->fd_bits & (1U << (fd))) != 0)

/*
 * I/O 多路复用 API
 */

/*
 * 函数功能：I/O 多路复用（select 模式）
 * 入口参数：nfds      - 最大 fd + 1（通常为 NET_MAX_SOCKETS）
 *          readfds   - 可读事件集合，NULL 表示不关心
 *          writefds  - 可写事件集合，NULL 表示不关心
 *          exceptfds - 异常事件集合，NULL 表示不关心
 *          timeout   - 超时时间，NULL 表示无限等待
 * 返回值：就绪的 fd 数量，0=超时，-1=错误
 * 限定条件：net_init() 已调用
 * 函数说明：此函数会调用 net_poll() 轮询所有 Socket，
 *          并检查哪些 Socket 有指定的事件发生。
 */
int net_select(int nfds, net_fd_set *readfds, net_fd_set *writefds,
               net_fd_set *exceptfds, net_timeval *timeout);

/*
 * 函数功能：I/O 多路复用（poll 模式）
 * 入口参数：fds     - net_pollfd 数组
 *          nfds    - 数组元素数量
 *          timeout - 超时时间（毫秒），-1 表示无限等待
 * 返回值：就绪的 fd 数量，0=超时，-1=错误
 * 限定条件：net_init() 已调用
 * 函数说明：与 select 类似，但使用 pollfd 结构体数组，
 *          更灵活，支持更多事件类型。
 */
int net_poll_events(net_pollfd *fds, int nfds, int timeout);

#ifdef __cplusplus
}
#endif

#endif /* __NET_SELECT_H */
