/**
 * @file xlt_trade_config.h
 * @author 上海前路有光数字科技
 * @date 2026-01-10
 * @brief 本文件定义XLT 交易API配置类
 */

#pragma once

#include <sys/socket.h>
#include <cstring>
#include "xlt_trade_data_type.h"

namespace x1 {

    class XLTTradeConfig {
    public:
        XLTTradeConfig() = default;
        /**
         * @brief 设置交易日，格式YYYYMMDD，如20230901
         * @param trading_day 交易日
         * @remark 用户需明确指定交易日，生产环境为当前交易日，测试环境为测试柜台指定的交易日
         */
        void set_trading_day(uint64_t trading_day) { trading_day_ = trading_day; }
        /**
         * @brief 设置本地网卡IP地址
         * @param agw 连接agw的本地网卡IP，生产环境需为AGW接入网段IP
         * @param trade 连接快速报单的本地网卡IP，生产环境需为快速报单网段IP
         * @return 设置是否成功
         * @remark 生产环境中，trade对应网卡建议为solarflare网卡，solarflare网卡将自动使用ef_vi，以便达到最优的性能，非solarflare网卡则回退到内核sock模式
         */
        bool set_local_addr(const char* agw, const char* trade);
        /**
         * @brief 添加网关地址
         * @param ip_addr agw IP地址
         * @param port agw端口
         * @return 设置是否成功
         * @remark 请向券商获取agw地址和端口，可重复调用添加多个agw地址，每次登录会随机选取当前可用的agw
         */
        bool add_agw_addr(const char* ip_addr, uint16_t port);
        /**
         * @brief 设置订单超时时间，单位秒，建议不小于10秒
         * @param timeout 超时时间
         * @remark 委托请求时，当达到此超时时间没有收到任何响应，将触发on_order_timeout回调，提示用户在此时间内未收到任何订单响应或回报，但不代表委托失败！！用户可选择调用resend_order_request接口重发订单。
         */
        void set_order_timeout(uint16_t timeout) { order_timeout_ = timeout; }
        /**
         * @brief 设置用户启用自定义订单序号
         * @param self_define 是否启用自定义订单序号
         * 默认情况下，API会自动生成订单序号，用户无需关心订单序号的生成规则；若用户启用自定义订单序号，则用户在每次下单时，必须在xlt_order_insert_info_t或xlt_cancel_order_info_t结构体中指定order_sequence字段
         * @remark 启用自定义订单序号后，用户必须确保每次下单时，order_sequence字段值唯一，否则可能导致重单，重单将没有任何响应！！！order_sequence字段取值范围[1, 2^20-1]
         * @remark 启用自定义订单序号后，建议委托和撤单使用不同的订单序号分段，以便管理委托和撤单，例如委托使用1~500000，撤单使用500001~1000000
         */
        void set_order_seq_self_define(bool self_define) { order_seq_self_define_ = self_define; }

        /*================= 以下为获取配置参数接口，为内部使用 ============*/
        /**
         * @brief 获取交易日，格式YYYYMMDD，如20230901
         * @return 交易日
         */
        uint64_t trading_day() const { return trading_day_; }
        /**
         * @brief 获取指定本地地址
         * @param index 0-AGW，1-交易
         * @return 本地地址
         */
        sockaddr get_local_addr(uint64_t index) const;
        /**
         * @brief 获取agw地址数量
         * @return agw地址数量
         */
        uint64_t agw_count() const { return agw_count_; };
        sockaddr* agw_addrs() { return agw_addr_; }
        /**
         * @brief 获取订单超时时间，单位秒
         * @return 订单超时时间
         */
        uint16_t order_timeout() const { return order_timeout_; }
        /**
         * @brief 获取是否用户自定义订单序号
         * @return 是否用户自定义订单序号
         */
        bool is_order_seq_self_define() const { return order_seq_self_define_; }

    private:
        uint64_t trading_day_ = 0;                          ///< 用户配置的交易日
        sockaddr local_addr_[2] = {};                       ///< 本地地址列表，0-AGW，1-交易
        uint64_t agw_count_ = 0;                            ///< AGW地址数量
        sockaddr agw_addr_[32] = {};                        ///< AGW地址列表
        uint16_t order_timeout_ = 10;                       ///< 订单超时时间，单位秒
        bool order_seq_self_define_ = false;                ///< 是否用户自定义订单序号
    };

}
