/**
 * @file xlt_quote_api.h
 * @author 上海前路有光数字科技
 * @date 2026-03-01
 * @brief 本文件定义XLT行情API接口类
 */

#pragma once

#include <cstdint>
#include <cstddef>
#include "xlt_quote_data_type.h"
#include "xlt_quote_define.h"
#include "xlt_quote_struct.h"
#include "xlt_quote_config.h"
#include "xlt_quote_list.h"

namespace x1 {

    /**
     * @brief 行情回调接口
     */
    class XLTQuoteSpi {
    public:
        XLTQuoteSpi() = default;
        virtual ~XLTQuoteSpi() = default;
        /**
         * @brief 断线通知
         * 用户断线之后需要重新调用login方法，建立连接并登录
         * @param session_id 会话ID。
         */
        virtual void on_disconnect(uint64_t session_id) {};
        /**
         * @brief 登录通知
         * @param session_id 本次登录生成的会话ID。如果登录失败则为0。
         * @param request_id 此消息响应函数对应的请求ID
         * @param error_info 登录请求发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误。
         */
        virtual void on_login(uint64_t session_id, uint64_t request_id, const xlt_error_info_t* error_info) {};
        /**
         * @brief 通用行情推送回调
         * @param mc_type 行情类型（QuoteMCType，唯一标记一条行情组播地址记录）
         * @param msg_data 行情消息数据指针（原始 UDP 包数据，不解码）
         * @param msg_len  消息长度（字节数），即 recvfrom() 返回的实际包长
         */
        virtual void on_quote(QuoteMCType mc_type, const void* msg_data, uint32_t msg_len) {};
        /**
         * @brief 查询全量静态行情信息响应
         * @param session_id 会话id，登录时得到
         * @param request_id 请求ID
         * @param static_quotes 本次响应返回的静态行情信息列表
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
         */
        virtual void on_query_static_quote_info(uint64_t session_id, uint64_t request_id, const XLTStaticQuoteList* static_quotes, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 查询level1行情响应
         * @param session_id 会话id，登录时得到
         * @param request_id 请求ID
         * @param level1_quote 本次响应返回的level1行情信息
         * @param error_info 查询发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         */
        virtual void on_query_level1_quote(uint64_t session_id, uint64_t request_id, const xlt_level1_quote_t* level1_quote, const xlt_error_info_t* error_info) {};
        /**
         * @brief 查询全量level1行情响应
         * @param session_id 会话id，登录时得到
         * @param request_id 请求ID
         * @param level1_quotes 本次响应返回的level1行情信息列表
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
         */
        virtual void on_query_all_level1_quote(uint64_t session_id, uint64_t request_id, const XLTLevel1QuoteList* level1_quotes, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 回补level2逐笔行情请求错误响应
         * @param session_id 会话id，登录时得到
         * @param request_id 请求ID
         * @param error_info 发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         */
        virtual void on_request_rebuild_tick_quote_error(uint64_t session_id, uint64_t request_id, const xlt_error_info_t* error_info) {};
        /**
         * @brief 回补level2逐笔行情数据推送
         * @param session_id 会话id，登录时得到
         * @param request_id
         * @param exchange_index 交易所
         * @param msg_type 数据类型
         * @param tick_quote 行情数据
         */
        virtual void on_rebuild_tick_quote(uint64_t session_id, uint64_t request_id, ExchangeIndex exchange_index, QuoteMsgType msg_type, const xlt_tick_quote_union_t* tick_quote) {};
    };

    /**
     * @brief 接口类
     */
    class XLTQuoteApi {
    public:
        /**
         * @brief 创建实例（只能创建一次）
         * @return 返回行情接口实例
         */
        static XLTQuoteApi* create();
        ~XLTQuoteApi() = default;
        /**
         * @brief 获取API版本号
         * @return API版本号
         */
        static const char* get_api_version();
        /**
         * @brief 获取错误信息
         * @return 错误信息
         */
        static xlt_error_info_t get_last_error();
        /**
         * @brief 获取当前交易日。只有登录成功后,才能得到正确的交易日。
         * @return 返回日期，格式为YYYYMMDD
         */
        uint32_t get_trading_day();
        /**
         * @brief 初始化行情，登录之前必须调用此函数，只能初始化一次
         * @param quote_config 配置参数
         * @param quote_spi 派生自行情响应类的实例，请在登录之前设定
         * @return 初始化是否成功
         */
        bool initialize(XLTQuoteConfig* quote_config, XLTQuoteSpi* quote_spi);
        /**
         * @brief 停止行情API
         * 断开所有行情session连接，清空所有session上的回调指针，停止回调。
         * @remark 调用stop后，所有未完成的回调将不再触发，用户可安全地释放对象。
         */
        void stop();
        /**
         * @brief 用户行情登录请求
         * @param request_id 用于用户定位请求响应的ID，由用户自定义
         * @param client_id 客户端标识ID
         * @param account_name 登录账号
         * @param password 登录密码
         * @param pub_key 用户公钥(长度64字节)，用户开户时申请得到
         * @param info 终端信息，若当前API为最终端则填nullptr，否则填写终端信息
         * @return 登录请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 行情API只能登录一次，如果需要重新登录，需要先调用logout登出，然后再调用login登录。登录成功后，API会创建一个会话，并在on_login回调中返回会话ID，用户需要保存这个会话ID，在后续的订阅、查询等请求中使用，以标识当前的登录状态和身份信息。
         */
        bool login(uint64_t request_id, uint16_t client_id, const char* account_name, const char* password, const char* pub_key, const xlt_user_terminal_info_t* info=nullptr);
        /**
         * @brief 行情登出请求
         * @param session_id 会话id，登录时得到
         * @return true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool logout(uint64_t session_id);
        /**
         * @brief 订阅行情请求
         * @param session_id 会话id，登录时得到
         * @param thread_count 行情接收线程数量
         * @param quote_threads 行情接收线程配置列表，每个元素包含一个线程的CPU亲和力设置和负责接收的行情组播类型列表
         * @param rx_mode 行情接收模式，默认为自动模式（QuoteRxMode::RX_MODE_AUTO），在自动模式下，API会根据系统环境和配置自动选择最优的接收模式（如ef_vi或内核socket）。用户也可以根据实际情况强制指定接收模式（如ef_vi模式或内核socket模式）。请注意，ef_vi模式需要满足特定的系统环境和配置要求，如使用Solarflare网卡，并正确设置网卡驱动和系统参数，否则可能无法正常工作或性能不佳。
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 订阅成功后，API会创建相应数量的行情接收线程，并绑定到指定CPU核心，同时订阅对应的行情组播地址，以便接收行情数据。请根据实际情况合理配置线程数量、CPU亲和力和组播类型分配，以获得最佳性能。
         */
        bool subscribe_quote(uint64_t session_id, uint16_t thread_count, quote_thread_t* quote_threads, QuoteRxMode rx_mode=QuoteRxMode::RX_MODE_AUTO);
        /**
         * @brief 退订行情请求
         * @param session_id 会话id，登录时得到
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 退订成功后，API会销毁所有行情接收线程，并退订所有行情组播地址，停止接收行情数据。请在不需要接收行情数据时调用此接口，以释放系统资源。
         */
        bool unsubscribe_quote(uint64_t session_id);
        /**
         * @brief 查询静态行情信息请求
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 查询结果将在on_query_static_quote_info回调中返回
         */
        bool query_static_quote_info(uint64_t session_id, uint64_t request_id);
        /**
         * @brief 查询level1行情请求
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param exchange_index 市场
         * @param security_code 证券代码
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 查询结果将在on_query_level1_quote回调中返回
         */
        bool query_level1_quote(uint64_t session_id, uint64_t request_id, ExchangeIndex exchange_index, const char* security_code);
        /**
         * @brief 查询全量level1行情请求
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 查询结果将在on_query_all_level1_quote回调中返回，由于全量level1行情数据较大，可能会分多条消息返回，请注意处理好回调中的is_last参数，以确定何时接收完毕。
         */
        bool query_all_level1_quote(uint64_t session_id, uint64_t request_id);
        /**
         * @brief 回补level2逐笔行情请求
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param request 回补请求
         * @return 请求发送是否成功，true表示成功，false表示出错。请求失败响应将在on_request_rebuild_tick_quote_error中返回，如果成功则直接在on_rebuild_tick_quote中推送回补数据。
         */
        bool request_rebuild_tick_quote(uint64_t session_id, uint64_t request_id, const xlt_rebuild_tick_quote_req_t* request);
    private:
        XLTQuoteApi()=default;
    };
}
