#pragma once

#include <cstdint>

#include "sse_hpf_define.h"
#include "sze_hpf_define.h"
#include "xlt_quote_define.h"

namespace x1::efh {

    typedef union efh_quote_data_union_t {
        const sse_hpf_lev2* sse_lev2_snap;                  ///< SSE_LEV2_SNAP_MSG_TYPE           (39)                    // 上交所lev2快照消息类型
        const sse_hpf_tick_merge* sse_lev2_tick_merge;      ///< SSE_LEV2_TICK_MERGE_MSG_TYPE     (62)                    // 上交所lev2逐笔合并信息类型
        const sse_hpf_idx* sse_lev2_idx;                    ///< SSE_LEV2_IDX_MSG_TYPE            (33)                    // 上交所lev2指数消息类型
        const sse_hpf_bond_snap* sse_lev2_bond_snap;        ///< SSE_LEV2_BOND_SNAP_MSG_TYPE      (60)                    // 上交所lev2债券快照信息类型
        const sse_hpf_bond_tick* sse_lev2_bond_tick;        ///< SSE_LEV2_BOND_TICK_MSG_TYPE      (61)                    // 上交所lev2债券逐笔信息类型
        const sze_hpf_lev2* sze_lev2_snap;                  ///< SZE_LEV2_SNAP_MSG_TYPE           (21)                    // 深交所快照消息类型
        const sze_hpf_order* sze_lev2_order;                ///< SZE_LEV2_ORDER_MSG_TYPE          (23)                    // 深交所订单消息类型
        const sze_hpf_exe* sze_lev2_exe;                    ///< SZE_LEV2_EXE_MSG_TYPE            (24)                    // 深交所成交消息类型
        const sze_hpf_idx* sze_lev2_idx;                    ///< SZE_LEV2_IDX_MSG_TYPE            (22)                    // 深交所指数消息类型
        const sze_hpf_bond_snap* sze_lev2_bond_snap;        ///< SZE_LEV2_BOND_SNAP_MSG_TYPE      (80)                    // 深交所债券快照消息类型
        const sze_hpf_bond_order* sze_lev2_bond_order;      ///< SZE_LEV2_BOND_ORDER_MSG_TYPE     (81)                    // 深交所债券逐笔委托消息类型
        const sze_hpf_bond_exe* sze_lev2_bond_exe;          ///< SZE_LEV2_BOND_EXE_MSG_TYPE       (82)                    // 深交所债券逐笔成交消息类型
    }efh_quote_data_union_t;

    /**
     * @brief get_next 返回的行情数据项
     */
    struct EFHQuoteItem {
        uint8_t data_type;                                  ///< 数据类型，用户根据此字段选择对应结构体解析 data
                                                            ///< SSE_LEV2_SNAP_MSG_TYPE           (39)                    // 上交所lev2快照消息类型
                                                            ///< SSE_LEV2_TICK_MERGE_MSG_TYPE     (62)                    // 上交所lev2逐笔合并信息类型
                                                            ///< SSE_LEV2_IDX_MSG_TYPE            (33)                    // 上交所lev2指数消息类型
                                                            ///< SSE_LEV2_BOND_SNAP_MSG_TYPE      (60)                    // 上交所lev2债券快照信息类型
                                                            ///< SSE_LEV2_BOND_TICK_MSG_TYPE      (61)                    // 上交所lev2债券逐笔信息类型
                                                            ///< SZE_LEV2_SNAP_MSG_TYPE           (21)                    // 深交所快照消息类型
                                                            ///< SZE_LEV2_ORDER_MSG_TYPE          (23)                    // 深交所订单消息类型
                                                            ///< SZE_LEV2_EXE_MSG_TYPE            (24)                    // 深交所成交消息类型
                                                            ///< SZE_LEV2_IDX_MSG_TYPE            (22)                    // 深交所指数消息类型
                                                            ///< SZE_LEV2_BOND_SNAP_MSG_TYPE      (80)                    // 深交所债券快照消息类型
                                                            ///< SZE_LEV2_BOND_ORDER_MSG_TYPE     (81)                    // 深交所债券逐笔委托消息类型
                                                            ///< SZE_LEV2_BOND_EXE_MSG_TYPE       (82)                    // 深交所债券逐笔成交消息类型
        efh_quote_data_union_t data;                        ///< 指向解码后数据的指针
    };

    /**
     * @brief 盛立行情解码迭代器
     *
     * 支持以下行情源：
     * QuoteMCType::HPF_SSE_L2_STOCK_SNAP
     * QuoteMCType::HPF_SSE_L2_STOCK_TICK
     * QuoteMCType::HPF_SSE_L2_INDEX
     * QuoteMCType::HPF_SSE_L2_BOND_SNAP
     * QuoteMCType::HPF_SSE_L2_BOND_TICK
     * QuoteMCType::HPF_SZSE_L2_STOCK_SNAP
     * QuoteMCType::HPF_SZSE_L2_STOCK_TICK
     * QuoteMCType::HPF_SZSE_L2_INDEX
     * QuoteMCType::HPF_SZSE_L2_BOND_SNAP
     * QuoteMCType::HPF_SZSE_L2_BOND_TICK
     *
     */
    class EFHQuoteDecoder {
    public:
        using StepFunc = const EFHQuoteItem* (*)(uint8_t*& data, uint32_t& remain, EFHQuoteItem& item);

        EFHQuoteDecoder(QuoteMCType mc_type, const void* msg_data, uint32_t msg_len);
        ~EFHQuoteDecoder() = default;
        /// 不可拷贝、不可移动
        EFHQuoteDecoder(const EFHQuoteDecoder&) = delete;
        EFHQuoteDecoder& operator=(const EFHQuoteDecoder&) = delete;

        /**
         * @brief 获取下一条解码后的行情数据
         * @return 非空指针表示一条有效数据，nullptr 表示遍历结束或构造时 mc_type 不支持
         * @note 返回的指针在下一次调用 get_next() 后失效（指向内部复用对象）
         * @note data 指针的生命周期与构造时传入的 msg_data 一致
         */
        const EFHQuoteItem* get_next();
    protected:
        StepFunc step_fn_;
        uint8_t* data_;
        uint32_t remain_;
        EFHQuoteItem item_;
    };

}
