/**
 * @file ws_client.h
 * @brief WebSocket 客户端封装 - 轻量级实现（无 libuwsc 依赖）
 * 
 * 功能:
 * - 连接到 WebSocket 服务器
 * - 发送文本/二进制消息
 * - 接收消息回调
 * - 线程安全的消息队列
 */

#ifndef WS_CLIENT_H
#define WS_CLIENT_H

#include <string>
#include <functional>
#include <atomic>
#include <thread>
#include <mutex>
#include <queue>
#include <vector>
#include <cstdint>

class WSClient {
public:
    using MessageCallback = std::function<void(const std::string&)>;
    
    /**
     * @brief 构造函数
     * @param host 服务器地址
     * @param port 服务器端口
     * @param path WebSocket 路径 (如 "/ws/camera")
     */
    WSClient(const std::string& host, int port, const std::string& path);
    ~WSClient();
    
    /**
     * @brief 连接到服务器
     * @return true 成功, false 失败
     */
    bool connect();
    
    /**
     * @brief 断开连接
     */
    void disconnect();
    
    /**
     * @brief 检查是否已连接
     */
    bool is_connected() const { return m_connected; }
    
    /**
     * @brief 发送文本消息
     * @param text 文本内容
     * @return true 成功, false 失败
     */
    bool send_text(const std::string& text);
    
    /**
     * @brief 发送二进制消息
     * @param data 二进制数据
     * @param size 数据大小
     * @return true 成功, false 失败
     */
    bool send_binary(const uint8_t* data, size_t size);
    
    /**
     * @brief 轮询消息 (处理接收到的消息)
     * @param callback 消息处理回调函数
     */
    void poll_messages(MessageCallback callback);
    
    /**
     * @brief 轮询二进制数据 (处理接收到的二进制帧)
     * @param callback 二进制数据处理回调函数 (data, size)
     */
    void poll_binary_messages(std::function<void(const uint8_t*, size_t)> callback);

private:
    std::string m_host;
    int m_port;
    std::string m_path;
    
    int m_sockfd;
    std::atomic<bool> m_connected;
    std::atomic<bool> m_running;
    
    std::thread m_recv_thread;
    
    // 发送队列
    struct Message {
        std::vector<uint8_t> data;
        bool is_binary;
    };
    std::queue<Message> m_send_queue;
    std::mutex m_send_mutex;
    
    // 接收队列 (文本消息)
    std::queue<std::string> m_recv_queue;
    std::mutex m_recv_mutex;
    
    // 接收队列 (二进制数据)
    std::queue<std::vector<uint8_t>> m_binary_queue;
    std::mutex m_binary_mutex;
    
    // 内部实现
    bool perform_handshake();
    void recv_loop();
    bool send_frame(const uint8_t* data, size_t len, uint8_t opcode);
    bool recv_frame(std::vector<uint8_t>& payload, uint8_t& opcode);
    void generate_mask_key(uint8_t* mask);
    
    // Day 12: 心跳机制 (使用普通 time_t 避免 32 位平台原子操作问题)
    time_t m_last_send_time = 0;  // 上次发送时间
    static const int HEARTBEAT_INTERVAL = 25;  // 心跳间隔（秒）
    void send_ping();  // 发送 PING 帧
    
    // WebSocket 操作码
    enum Opcode {
        OP_CONTINUATION = 0x0,
        OP_TEXT = 0x1,
        OP_BINARY = 0x2,
        OP_CLOSE = 0x8,
        OP_PING = 0x9,
        OP_PONG = 0xA
    };
};

#endif // WS_CLIENT_H
