/* generated by handle_module_spi */

use crate::v1alpha1::bindings::*;

pub trait MdSpi: Send {   
    /// 当客户端与交易后台建立起通信连接时（还未登录前），该方法被调用。
    fn on_front_connected(&mut self) {
    }
   
    /// 当客户端与交易后台通信连接断开时，该方法被调用。当发生这个情况后，API会自动重新连接，客户端可不做处理。
    ///@param nReason 错误原因
    ///         0x1001 网络读失败
    ///         0x1002 网络写失败
    ///         0x2001 接收心跳超时
    ///         0x2002 发送心跳失败
    ///         0x2003 收到错误报文
    fn on_front_disconnected(&mut self, n_reason: i32) {
    }
   
    /// 心跳超时警告。当长时间未收到报文时，该方法被调用。
    ///@param nTimeLapse 距离上次接收报文的时间
    fn on_heart_beat_warning(&mut self, n_time_lapse: i32) {
    }
   
    /// 登录请求响应
    fn on_rsp_user_login(&mut self, p_rsp_user_login: Option<&CThostFtdcRspUserLoginField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 登出请求响应
    fn on_rsp_user_logout(&mut self, p_user_logout: Option<&CThostFtdcUserLogoutField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 请求查询组播合约响应
    fn on_rsp_qry_multicast_instrument(&mut self, p_multicast_instrument: Option<&CThostFtdcMulticastInstrumentField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 错误应答
    fn on_rsp_error(&mut self, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 订阅行情应答
    fn on_rsp_sub_market_data(&mut self, p_specific_instrument: Option<&CThostFtdcSpecificInstrumentField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 取消订阅行情应答
    fn on_rsp_unsub_market_data(&mut self, p_specific_instrument: Option<&CThostFtdcSpecificInstrumentField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 订阅询价应答
    fn on_rsp_sub_for_quote_rsp(&mut self, p_specific_instrument: Option<&CThostFtdcSpecificInstrumentField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 取消订阅询价应答
    fn on_rsp_unsub_for_quote_rsp(&mut self, p_specific_instrument: Option<&CThostFtdcSpecificInstrumentField>, p_rsp_info: Option<&CThostFtdcRspInfoField>, n_request_id: i32, b_is_last: bool) {
    }
   
    /// 深度行情通知
    fn on_rtn_depth_market_data(&mut self, p_depth_market_data: Option<&CThostFtdcDepthMarketDataField>) {
    }
   
    /// 询价通知
    fn on_rtn_for_quote_rsp(&mut self, p_for_quote_rsp: Option<&CThostFtdcForQuoteRspField>) {
    }
}

#[repr(C)]
#[derive(Debug)]
pub struct MdSpiVTable {
    on_front_connected: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt),
    on_front_disconnected: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, n_reason: std::os::raw::c_int),
    on_heart_beat_warning: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, n_time_lapse: std::os::raw::c_int),
    on_rsp_user_login: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_rsp_user_login: *const CThostFtdcRspUserLoginField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_user_logout: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_user_logout: *const CThostFtdcUserLogoutField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_qry_multicast_instrument: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_multicast_instrument: *const CThostFtdcMulticastInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_error: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_sub_market_data: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_unsub_market_data: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_sub_for_quote_rsp: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rsp_unsub_for_quote_rsp: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool),
    on_rtn_depth_market_data: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_depth_market_data: *const CThostFtdcDepthMarketDataField),
    on_rtn_for_quote_rsp: unsafe extern "C" fn(spi: *mut CThostFtdcMdSpiExt, p_for_quote_rsp: *const CThostFtdcForQuoteRspField),
}

static SPI_VTABLE: MdSpiVTable = MdSpiVTable {
    on_front_connected: spi_on_front_connected,
    on_front_disconnected: spi_on_front_disconnected,
    on_heart_beat_warning: spi_on_heart_beat_warning,
    on_rsp_user_login: spi_on_rsp_user_login,
    on_rsp_user_logout: spi_on_rsp_user_logout,
    on_rsp_qry_multicast_instrument: spi_on_rsp_qry_multicast_instrument,
    on_rsp_error: spi_on_rsp_error,
    on_rsp_sub_market_data: spi_on_rsp_sub_market_data,
    on_rsp_unsub_market_data: spi_on_rsp_unsub_market_data,
    on_rsp_sub_for_quote_rsp: spi_on_rsp_sub_for_quote_rsp,
    on_rsp_unsub_for_quote_rsp: spi_on_rsp_unsub_for_quote_rsp,
    on_rtn_depth_market_data: spi_on_rtn_depth_market_data,
    on_rtn_for_quote_rsp: spi_on_rtn_for_quote_rsp, 
};

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CThostFtdcMdSpiExt {
    vtable: *const MdSpiVTable,
    pub spi_ptr: *mut dyn MdSpi,
}

impl CThostFtdcMdSpiExt {
    pub fn new(spi: *mut dyn MdSpi) -> Self {
        Self {
            vtable: &SPI_VTABLE,
            spi_ptr: spi,
        }
    }
}


extern "C" fn spi_on_front_connected(spi: *mut CThostFtdcMdSpiExt) {
    unsafe {
        (*(*spi).spi_ptr).on_front_connected()
    }
}

extern "C" fn spi_on_front_disconnected(spi: *mut CThostFtdcMdSpiExt, n_reason: std::os::raw::c_int) {
    unsafe {
        (*(*spi).spi_ptr).on_front_disconnected(n_reason)
    }
}

extern "C" fn spi_on_heart_beat_warning(spi: *mut CThostFtdcMdSpiExt, n_time_lapse: std::os::raw::c_int) {
    unsafe {
        (*(*spi).spi_ptr).on_heart_beat_warning(n_time_lapse)
    }
}

extern "C" fn spi_on_rsp_user_login(spi: *mut CThostFtdcMdSpiExt, p_rsp_user_login: *const CThostFtdcRspUserLoginField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_user_login(p_rsp_user_login.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_user_logout(spi: *mut CThostFtdcMdSpiExt, p_user_logout: *const CThostFtdcUserLogoutField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_user_logout(p_user_logout.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_qry_multicast_instrument(spi: *mut CThostFtdcMdSpiExt, p_multicast_instrument: *const CThostFtdcMulticastInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_qry_multicast_instrument(p_multicast_instrument.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_error(spi: *mut CThostFtdcMdSpiExt, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_error(p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_sub_market_data(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_sub_market_data(p_specific_instrument.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_unsub_market_data(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_unsub_market_data(p_specific_instrument.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_sub_for_quote_rsp(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_sub_for_quote_rsp(p_specific_instrument.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rsp_unsub_for_quote_rsp(spi: *mut CThostFtdcMdSpiExt, p_specific_instrument: *const CThostFtdcSpecificInstrumentField, p_rsp_info: *const CThostFtdcRspInfoField, n_request_id: std::os::raw::c_int, b_is_last: bool) {
    unsafe {
        (*(*spi).spi_ptr).on_rsp_unsub_for_quote_rsp(p_specific_instrument.as_ref(), p_rsp_info.as_ref(), n_request_id, b_is_last)
    }
}

extern "C" fn spi_on_rtn_depth_market_data(spi: *mut CThostFtdcMdSpiExt, p_depth_market_data: *const CThostFtdcDepthMarketDataField) {
    unsafe {
        (*(*spi).spi_ptr).on_rtn_depth_market_data(p_depth_market_data.as_ref())
    }
}

extern "C" fn spi_on_rtn_for_quote_rsp(spi: *mut CThostFtdcMdSpiExt, p_for_quote_rsp: *const CThostFtdcForQuoteRspField) {
    unsafe {
        (*(*spi).spi_ptr).on_rtn_for_quote_rsp(p_for_quote_rsp.as_ref())
    }
}
