#pragma once

#include <vector>
#include <string>
#include <iostream>
#include <atomic>

#include <onepiece/api/ctp/ThostFtdcMdApi.h>
#include <onepiece/models/AccountModel.h>

#include <onepiece/templates/ICoreListener.h>
#include <onepiece/templates/IMarketApi.h>

using namespace std;

class MarketCTP: public IMarketApi, public CThostFtdcMdSpi
{

public:
    MarketCTP() = delete;
    MarketCTP(AccountSPtr accountPtr);
    virtual ~MarketCTP();

public:
    virtual bool Connect();
    
    virtual bool Disconnect();

    virtual void Subscribe(const shared_ptr<vector<string>> instruments);

    virtual void Unsubscribe(const shared_ptr<vector<string>> instruments);

    virtual bool RegisterListener(ICoreListener* coreListener);


public:
    virtual void OnFrontConnected();

    virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

    virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData);

    virtual void OnFrontDisconnected(int nReason);

    virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

    virtual void OnHeartBeatWarning(int nTimeLapse);

private:
    inline string GetDisconnectedReason(int reason) {
        switch (reason) {
            case 0x1001:
                return "网络读失败";
            case 0x1002:
                return "网络写失败";
            case 0x2001:
                return "接收心跳超时";
            case 0x2002:
                return "发送心跳失败";
            case 0x2003:
                return "收到错误报文";
            default:
                return "Unknown";
        }
    };

    inline uint32_t MakeRequestID() {
        return this->m_nRequestID.fetch_add(1) + 1;
    }

private:
    CThostFtdcMdApi *m_api;
    atomic<uint32_t> m_nRequestID;
    AccountSPtr m_accountPtr;

    ICoreListener* m_coreListener;
};