#ifndef __TYPHOON_H__
#define __TYPHOON_H__

#include <vector>
#include "uv.h"
#include "YyAuthenticationManageFile.h"
#include "TyphoonDefine.h"

#ifdef WIN32
#ifdef _DLL_SAMPLE
#define TYPHOON_API __declspec(dllexport)
#else
#define TYPHOON_API __declspec(dllimport)
#endif
#else
#define TYPHOON_API
#endif

#ifndef SOCKADDR
typedef struct sockaddr SOCKADDR;
#endif


typedef struct ControlPackets
{
    /* 控制指令, 包括notify/handshake/Ack */
    int64_t m_NotifyCount;                          //Notify消息数量
    int64_t m_NotifySize;                           //Notify消息大小
    int64_t m_HandShakeCount;                       //心跳报文的数量
    int64_t m_HandShakeSize;                        //心跳报文的大小
    int64_t m_AckCount;                             //Ack报文的数量
    int64_t m_AckSize;                              //Ack报文的大小
    int64_t m_SackCount;                            //Sack报文的数量
    int64_t m_SackSize;                             //Sack报文的大小
    int64_t m_NatKeepAliveCount;                    //NAT保活报文数量
    int64_t m_NatKeepAliveSize;                     //NAT保活报文大小
    int64_t m_ForceSyncCount;						//Partial Reliable功能中的强制同步窗口命令数量
    int64_t m_ForceSyncSize;						//Partial Reliable功能中的强制同步窗口命令大小
}stControlPackets;




struct ITyphoonInfo:public TyphoonConnStats         //1条连接的统计信息
{    
    int64_t m_CurrentSendSpeed;                      //当前的发送速度 字节/秒

    std::vector<uint32_t>  m_resendStatistic;             //重发统计, [0]为重发1次的报文记录, [1]位重发2次的

    stControlPackets m_RxStats;                     //控制报文接收统计
    stControlPackets m_TxStats;                      //控制报文发送统计

    /* 连接建立时间 */
    time_t m_ConSetupTime;                           //连接建立时间

	//连接上IsWritable返回false的次数
	uint32_t m_UnWritableCount;

	//连接上因为对端缓冲区满的次数
	uint32_t m_PeerNoBufferCount;

	//连接上因为Unack的报文太多的次数
	uint32_t m_TooManyUackPackCount;

	//连接上因为TickDataSize不够的次数
	uint32_t m_NoTickDataSize;

	//连接上因为TooFast属性被暂停发送的报文
	uint32_t m_TooFastCount;
};

typedef TyphoonCfg ITyphoonCfg;

//Single Typhoon Connection configuration
class TYPHOON_API ITyphoonConnCfg
{
public:
    uint32_t MaxQueueSize;                 //Max Size of Typhoon connection send and recv queue size    
    uint32_t FixedSendSpeed;               //连接的固定发送速度, 默认为0表示不设置, 由typhoon自动探测发送速度; 
                                           //如该值设置后, typhoon内部发送速度探测算法不再生效, 连接每秒发送速度的按照用户设置值进行
    uint32_t MaxSendSpeed;                 //连接的最大发送速度, 默认为0表示不设置;
                                           //如该选项进行了设置, 实时发送速度依然由typhoon内部算法决定, 但是连接最大的速度不能超过本设置值
    uint32_t MinSendSpeed;                 //如该选项进行了设置, Typhoon的发送速度不低于该值
    uint16_t MaxChannelSize;               //每条连接可以建立的channel数量
    uint16_t MaxSegmentSize;               //Typhonn协议每个报文的最大值
    uint32_t SendBuffSize;                 //连接发送缓存大小, 这个配置仅影响初始发送缓冲值, typhoon算法会自动计算发送缓存大小最优值, 以保证发送效率
    uint32_t RecvBuffSize;                 //连接接收缓存大小
    uint8_t  UseThreadForAppDataCb;        //配置当前连接是否使用额外的线程执行用户数据通知回调, 默认为0, 即回调函数不使用额外的线程处理
                                           //取值范围[0, 1]
    uint8_t  CompressMethod;               //连接支持的压缩方法, 可以设置为支持1种或多种方法, 通过enTyphoonCompressMethod的值 | 得到结果
    uint8_t  TransferMode;                 //连接传输模式, 分为文件传输模式0, 实时传输模式1, 默认为0
    uint8_t  UseDataPush;				   //当数据达到时, PushData的方式是调用OnRead回调, 非PushData(PullData)的方式是调用OnDataArrived回调
    										//两种方式没有本质区别, 区别在于OnRead回调让用户必须立刻马上处理这个数据, 而OnDataArrived只是通知用户数据达到了, 用户可以选择马上处理或者不马上处理
public:
    ITyphoonConnCfg();
};


//typhoon utils

//事件类, 用于线程间信息同步
class TYPHOON_API IWaitEvent                
{
public:
    /* 在当前事件上等待指定时间, 单位ms
       如果在指定时间内被唤醒, 在唤醒时刻立刻返回; 
       如果在指定时间内没有收到事件, 则在超时后返回 */
    virtual int Wait(uint64_t ms) = 0;

    /* 一直等待, 直到被Signal唤醒 */
    virtual void Wait() = 0;

    /* 触发事件 */
    virtual void Signal() = 0;
};






class TYPHOON_API ITyphoonBuff
{
public:
    //获取缓存报文头指针
    virtual uint8_t* GetBuff(void) = 0;  

    //获取缓存报文长度
    virtual int32_t GetLen(void) = 0;     

    //释放缓存实例
    virtual void Destroy() = 0;             
    virtual ~ITyphoonBuff(){}
};

class TYPHOON_API ITyPhoonChannel;
class TYPHOON_API ITyPhoonConnCallBack;
class TYPHOON_API ITyPhoonConn;
class TYPHOON_API ITyphoon;

//遍历同一条连接下的所有channel回调原型
typedef void (*TyphonnConn_TraverseChannels_Cb)(ITyPhoonConn *pConn, ITyPhoonChannel *pChan, void* arg);

//连接遍历回调
typedef void (*Typhoon_TraverseConnections_Cb)(ITyphoon *pTyphoon, ITyPhoonConn *pConn, void* arg);


//同步执行回调
typedef int (*Typhoon_SynchronizedExecute_Cb)(void* arg);


class TYPHOON_API ITyPhoonChannel 
{
public:
    /* channel 是否可写 */
    virtual bool IsWritable() = 0;

    /* 发送数据接口
        pData: 数据首地址指针
        len: 数据长度
        compresLevel: 压缩级别, 有效范围[0, 19], 0表示不压缩;
                      [1, 19]是有效压缩级别, 越小压缩速度越快, 但是压缩效果较普通, 越大压缩效果越好, 但是耗时越长
                      当使用压缩时, 建议pData的数据, len长度为128KB, 这个值仅仅是建议, 不是强制要求
        lifeTime: 报文的生命周期, 单位为毫秒; 
                  当lifeTime为0时, 表示不设置生命周期, 该报文确保会被发送到对端;
                  当lifeTime不为0时, 在lifeTime时间内, Typhoon协议会尝试重发将报文发送到对端, 当超过lifeTime时间后,
                  该报文被放弃发送   
        maxSendCount: 报文最大发送次数
                      当maxSendCount为0时, 表示不设置发送次数限制, 该报文会确保被发送到对端
                      当maxSendCount不为0时, Typhoon协议最大尝试maxSendCount次重发, 每个RTT重发一次, 即尝试RTT*maxSendCount时间
        fecPercent: FEC保护报文的比例, 该值在0-10000之间, 采用的是万分之fecPercent
                    fecPercent为500代表万分之500, 即5%的冗余率. 
        			fec报文的数量 = (len/mss + 1) * fecPercent/10000
        			fec报文的大小 = mss
        备注: 1) 本接口的内置智能压缩功能, 如果发送时通过compresLevel指定了压缩, 但是内部进行实际压缩计算时发现数据压缩后比压缩前还大
              将自动放弃压缩的结果, 使用原始数据进行传输;
              2) 压缩是针对每次Send的数据单独进行的, 同一个channel, 用户可以选择第一次Send进行压缩, 第二次Send不进行压缩;
    */
    virtual bool Send(uint8_t* pData,int32_t len, 
    				uint8_t compresLevel=0, uint32_t lifeTime=0, uint8_t maxSendCount=0, uint16_t fecPercent=0) = 0; 

 
    virtual ITyphoonBuff *Recv() = 0; 


    /* 关闭一个Channel */
    virtual int32_t Close() = 0; 

    /* 关闭本端channel的写 */
    virtual int32_t Shutdown() = 0;   

    //channel用户自定义数据, 可以是指针, 数据内容由用户层自行定义和解释, Typhoon内部只保存, 不理解处理该字段
    virtual void SetUserData(uint64_t Data) = 0; 
    virtual uint64_t GetUserData() = 0;    

    //打开/关闭channel的可写检测回调开关, 当开关打开时, Typhoon会调用应用注册的OnSentDataAcknowledged
    virtual void EnableWritableWatch() = 0;
    virtual void DisableWritableWatch() = 0;
    virtual uint8_t GetWritableWatch() = 0;

    //获取channel下未确认的数据长度
    //返回值
    virtual int64_t GetUnackedDataLength() = 0;       


    //获取channelID
    //返回值:channelID
    virtual uint16_t ChannelId() = 0;

    //显示Channel当前信息, 调试使用
    virtual void ShowChannel() = 0;

    //channel是客户端打开的还是服务端打开的
    virtual bool OpenByClient() = 0;

    virtual bool OpenByServer() = 0;

    virtual bool OpenByMyself() = 0;
};



class TYPHOON_API ITyPhoonFecTunnel 
{
public:


    virtual bool Send(uint8_t* pData,int32_t len, uint8_t maxSendCount=0) = 0; 

 
    virtual ITyphoonBuff *Recv() = 0; 


    /* 关闭一个FecTunnel */
    virtual int32_t Close() = 0; 

    //FecTunnel用户自定义数据, 可以是指针, 数据内容由用户层自行定义和解释, Typhoon内部只保存, 不理解处理该字段
    virtual void SetUserData(uint64_t Data) = 0; 
    virtual uint64_t GetUserData() = 0;    

   
    virtual uint16_t TunnelId() = 0;
};




class TYPHOON_API ITyPhoonConn 
{
public:
    /* 客户端主动连接服务器
       ip: 服务器ip地址
       port: 服务器端口
       sync: 函数是同步阻塞操作还是异步非阻塞操作
             sync = false  异步非阻塞操作, ConnectTo马上返回, 实际的连接结果在OnConnected回调函数中获取
             sync = true   同步阻塞操作 ConnectTo 一直阻塞等到连接完成返回;
       data
       data_len  Typhoon支持在建立连接过程中客户端向服务端发送数据, data为数据的首地址, data_len为数据长度
    */
    virtual int32_t ConnectTo(char *ip, uint16_t port, bool sync=false, 
                        uint8_t *data=NULL, uint16_t data_len=0) = 0; 
    virtual int32_t  ConnectToEx(char *ip, uint16_t port, char *bind_ip, uint16_t bind_port, 
                                bool sync=false, uint8_t *data=NULL, uint16_t data_len=0) = 0; 

    /* 关闭连接 */                        
    virtual void Destroy() = 0;
    
    /* 连接是否建立 */
    virtual bool IsConnected() = 0;                        

    /* 打开一个新的Channel, 返回ITyPhoonChannel对象, 如果返回值为NULL, 则打开channel失败 */
    virtual ITyPhoonChannel *OpenChannel() = 0;

    /* 获取连接的对端地址 */
    virtual SOCKADDR *GetRemoteAddr() = 0;                

    /* Typhoon连接定时器设置 */
    virtual void SetTimeout(stTyphoonTimerConfig *pCfg) = 0;
    virtual stTyphoonTimerConfig GetTimeout() = 0;

    /* 查询当前连接的实际打开的channel数量, 包括默认0 channel, 因此即使用户没有调用OpenChannel接口, 也存在1个channel */
    virtual uint16_t QueryChannelCount() = 0;   

    /* 获得当前连接的RTT信息, 单位: 毫秒 */
    virtual uint32_t QueryRTT() = 0;

    /* 获得当前连接的丢包率信息, 单位: 万分之X */
    virtual uint32_t QueryDropRate(bool bLast10Sec=true) = 0;

    virtual int32_t GetMaxAuthSendSpeed() = 0;

    /* MaxSegmentSize, 单个Typhoon报文的最大长度, 与用户的网络MTU相关 
       SetMaxSegmentSize 设置本端的Mss
       GetMaxSegmentSize 获取设置的Mss大小
       QueryMaxSegmentSize 获取实际的Mss大小, 实际的Mss值是客户端与服务端之间在建立连接过程中协商出来的
                           可能小于设置值
    */
    virtual void SetMaxSegmentSize(uint16_t Mss) = 0;
    virtual uint16_t GetMaxSegmentSize() = 0;
    virtual uint16_t QueryMaxSegmentSize() = 0;       

    //连接用户自定义数据, 可以是指针, 数据内容由用户层自行定义和解释, Typhoon内部只保存, 不理解处理该字段
    virtual void SetUserData(uint64_t Data) = 0; 
    virtual uint64_t GetUserData() = 0;
   
    //连接发送缓存大小, 所有的Channel共用发送缓存
    virtual void SetSendBuffSize(uint32_t Size) = 0;      
    virtual uint32_t GetSendBuffSize() = 0;                    

    //接收缓存大小, 所有的Channel共用发送缓存
    virtual void SetRecvBuffSize(uint32_t Size) = 0;
    virtual uint32_t GetRecvBuffSize() = 0;                        

    //连接回调, 每条连接可以设置不同的回调函数
    virtual void SetConnCallback(ITyPhoonConnCallBack *) = 0; 
    virtual ITyPhoonConnCallBack *GetConnCallback() = 0; 

    /* 设置连接固定发送速度, 固定发送速度被设置为大于0后, Typhoon将按照设置的速度进行数据发送 
       Size: 发送速度, 单位为bytes/sec
    */
    virtual void SetFixedSendSpeed(uint32_t Size) = 0;

    /* 获取固定发送速度的设置值 */
    virtual uint32_t GetFixedSendSpeed() = 0;  

    /* 设置最大发送速度 , 设置连接的发送速度上限
       Size: 最大发送速度, 单位为bytes/sec
    */
    virtual void SetMaxSendSpeed(uint32_t Size) = 0;

    /* 获取最大发送速度 */
    virtual uint32_t GetMaxSendSpeed() = 0;     


    //设置最小发送速度
    virtual void SetMinSendSpeed(uint32_t Size) = 0;
    virtual uint32_t GetMinSendSpeed() = 0;  
	virtual int64_t GetCurSendSpeed() = 0;  

	virtual void SetCompress(uint8_t     CompressMethod) = 0;
    virtual uint32_t GetCompress() = 0;

	virtual void AuthChange() = 0;
	virtual void setAuth(sTyphoonProxyLicense  *license) = 0;
	
    virtual void GetWanAddr(struct sockaddr *addr) = 0;
    virtual void GetRemoteAddr(struct sockaddr *addr) = 0;

    //遍历连接下所有存在的channel
    virtual void TraverseChannels(TyphonnConn_TraverseChannels_Cb traverse_cb, void* arg) = 0;

    //获取连接的默认通道, 即通道0
    virtual ITyPhoonChannel *GetDefaultChannel() = 0;

    //关闭当前连接下所有的channel
    virtual void ShutdownAllChannels() = 0;

    //根据ChannelId 获取Channel实例, 如果Cid找不到, 返回NULL
    virtual ITyPhoonChannel *GetChannel(uint16_t Cid) = 0;

    /* 获取对端RTT */
    virtual uint32_t QueryPeerRtt() = 0;

    /* 获取对端丢包率 */    
    virtual uint32_t QueryPeerDropRate(bool bLast10Sec=true) = 0;

    virtual ITyphoonInfo *GetStats() = 0;

    /* 设置连接的传输模式 TransferMode 0代表文件传输模式, 1代表实时传输模式 */
    virtual uint8_t SetTransferMode(uint8_t TransferMode) = 0;

    /* 获取当前连接的传输模式 TransferMode 0代表文件传输模式, 1代表实时传输模式 */
    virtual uint8_t GetTransferMode() = 0;  
    /* 连接角色是客户端还是服务端 */
    virtual bool IsClient() = 0;
    virtual bool IsServer() = 0;

	/* Typhoon协议内置丢包模拟器, 用于日常测试
	   SetPacketLoss  设置丢包率, 为万分之Percent, 如果要设置5%的丢包, Percent需要设置为500
	   GetPacketLoss  获得目前设置的丢包率, 丢包率为0代表未设置丢包
	   IsPacketLossSet 是否设置了丢包率, 如果返回真, 则GetPacketLoss() > 0

	   丢包模拟器使用伪随机算法进行处理, 
	   对每个报文做随机丢包处理会消耗较多的CPU, 尤其在传输速度很高时, 如每秒需发送数万个报文
	   因此本功能仅作为方便内部测试使用, 不要在真实传输场景中打开
	*/
	virtual uint16_t GetPacketLoss() = 0;
	virtual void SetPacketLoss(uint16_t Percent) = 0;
	virtual bool IsPacketLossSet() = 0;
	
	virtual ITyPhoonFecTunnel * OpenFecTunnel(uint16_t channelCount) = 0;
    virtual void CloseFecTunnel(uint16_t tunnelId) = 0;

    
    virtual ~ITyPhoonConn(){}
};









class TYPHOON_API ITyPhoonConnCallBack
{
public:
    /* 连接结果通知回调 
       pConn: 连接指针
       erro:  通知结果
       data: (仅对连接的服务端有效)如果连接成功并且data不为空, 收到客户端在发起连接时发送的数据
       data_len: data指针表示的数据长度
    */
    virtual void OnConnected(ITyPhoonConn* pConn, enTyphoonErr erro, uint8_t* data, uint16_t data_len) = 0;

    /*
        连接中断通知回调
        pConn: 连接指针
        cause: 中断原因
    */    
    virtual void OnDisconnected(ITyPhoonConn* pConn, enTyphoonDisconnectCause cause) = 0;

    /*
        PUSH模式下, Typhoon收到收据后主动通知应用回调
        在非线程回调模式下, 应用层不能在OnRead回调中做阻塞操作
        在线程回调模式下, 应用层可以在OnRead回调中做阻塞操作
        pConn: 连接指针
        pChan: 数据所属的channel指针
        pData: 数据指针
        len: 数据长度
    */        
    virtual void OnRead(ITyPhoonConn * pConn,ITyPhoonChannel *pChan,uint8_t* pData,int32_t len){} 


    /*
        Channel可写回调
        在非线程回调模式下, 应用层不能在OnWritable回调中做阻塞操作
        在线程回调模式下, 应用层可以在OnWritable回调中做阻塞操作        
        pConn: 连接指针
        pChan: 数据所属的channel指针
    */        
    virtual void OnWritable(ITyPhoonConn * pConn, ITyPhoonChannel *pChan){} 


    /*
        发送的数据被对方确认回调
        备注: 应用层在本回调函数中不能执行阻塞操作
        pConn: 连接指针
        pChan: 数据所属的channel指针
        ackLen: 被确认的数据长度
    */      
    virtual void OnSentDataAcknowledged(ITyPhoonConn * pConn, ITyPhoonChannel *pChan, int32_t ackLen){}
    
    /*
        PULL模式下, Typhoon收到收据后主动通知应用回调, 应用层可以根据处理情况调用Recv接口
        pConn: 连接指针
        pChan: 数据所属的channel指针
    */    
    virtual void OnDataArriveNotify(ITyPhoonConn *pConn, ITyPhoonChannel *pChan){}

    
    /*
      新的Channel打开回调, 本接口仅用于Channel的被动打开方, 对于主动打开方, 只需要调用OpenChannel
      pConn: 连接指针
      pChan: 数据所属的channel指针
    */    
    virtual void OnChannelOpen(ITyPhoonConn *pConn, ITyPhoonChannel *pChan){}

    /*
      Channel 关闭回调
      触发时机: 当对端调用CloseChannel接口直接关闭Channel时, 会触发本端的OnChannelClose
                上层应用需要在OnChannelClose完成该Channel相关的资源清理工作
      注意: 1) 当收到OnChannelClose回调时, 该channel已经无法用于通信, 用户不要在该Channel上进行Channel相关的任何操作;
            2) 本地Channel已经自动关闭, 不需要应用调用CloseChannel去关闭本地Channel
      pConn: 连接指针
      pChan: 数据所属的channel指针   
      closeType: 引发关闭的原因
    */
    virtual void OnChannelClose(ITyPhoonConn *pConn, ITyPhoonChannel *pChan, enChannelCloseType closeType){}

    virtual void OnAuthChange(ITyPhoonConn *pConn, sTyphoonProxyLicense *license){}

 
	/* 定时器回调, 在连接建立成功后会调用该函数.
	   调用者可以通过返回值来指示希望下一次触发该回调的时间
	   相当于一个定时器. 比如返回5表示5毫秒后触发该定时器
	   返回值为0: 表示继续使用当前的触发超时时间
	   OnTimer默认10毫秒调用一次
	   	
	   应用场景: 调用者经常需要定时发送一些数据, 可以在本回调中进行
	   调用者可以借用ITyPhoonConn的UserData信息去保存处理任务相关的信息
	   注意事项: OnTimer运行在Typhoon协议线程上, 回调函数中不能有阻塞或需要处理很长时间(比如大于1毫秒)的工作
	   否则会将Typhoon协议处理线程阻塞住, 导致协议的发送和接受数据受影响
	*/
    virtual uint32_t OnTimer(ITyPhoonConn* pConn) { return 0; }


	/* SDN 节点与连接对端Peer的路由方式
	   pConn: 连接指针
	   type: 路由方式
	   TYPHOON_SDN_RELAY : 与对端节点通过中转节点通信
	   TYPHOON_SDN_DIRECT: 与对端节点建立了直连通信 

	   本回调函数仅在SDN模式下有效, 非SDN模式该函数不会被调用
	*/	
    virtual void OnSDNRouteChange(ITyPhoonConn* pConn, enTyphoonSDNPathType type) {}
	
};



class TYPHOON_API ITyphoon
{
public:
    /* 初始化Typhoon的底层UDP socket
       ip: socket监听的本地ip地址, NULL表示侦听所有的地址
       port: socket监听的本地端口, 0表示由系统分配侦听端口, 常用于客户端
    */   
    virtual bool InitUDPSocket(char* ip = NULL,uint16_t port = 0) = 0;

    /*
        设置App的初始化函数
    */
    virtual void SetAppInitCB(Typhoon_AppInit_Callback Init) = 0;

    /*
        设置App的退出析构函数
    */
    virtual void SetAppUninitCB(Typhoon_AppUninit_Callback Uninit) = 0;

    /* 获取Typhoon实例的Libuv Loop实例, 仅仅在应用希望与Typhoon运行在同一个线程时调用, 
       使用该接口后, 应用必须适用libuv相关接口 */
    virtual uv_loop_t *GetMainLoop() = 0;

    /* 设置连接的全局默认回调函数
       pSink: 回调函数实例指针
    */      
    virtual void SetConnCallback(ITyPhoonConnCallBack *pSink) = 0; 

    /* 获取连接的全局默认回调函数
    */
    virtual ITyPhoonConnCallBack *GetConnCallback() = 0;    

    /* 获取本地UDP socket的绑定地址 */    
    virtual SOCKADDR GetLocalAddr() = 0;                                    

    /* 获取当前的连接数量 */
    virtual int32_t GetConnectionCount() = 0;                               

    /* 创建一个连接实例 */
    virtual ITyPhoonConn* CreateConnection() = 0;        

    /* 获取全局配置信息 */
    virtual ITyphoonCfg  GetTyphoonConfig() = 0;          

    /* 设置全局配置信息 */
    virtual void  SetTyphoonConfig(ITyphoonCfg cfg) = 0; 

    /* 获取连接的全局默认配置 */
    virtual ITyphoonConnCfg GetConnDefaultCfg() = 0;

    /* 设置连接的全局默认配置 */
    virtual void SetConnDefaultCfg(ITyphoonConnCfg *) = 0;


    /* 激活Typhoon License 
       licenseCode: License编号
       ProductType: 产品类型
       返回值: > 0 激活成功, 返回值表示该License的网络带宽值(单位Mbps)
               = 0 激活失败
       备注: 该函数为阻塞操作, 一直会等到网络激活结果后才会返回
    */
    virtual int ActivateLicense(char *licenseCode, int ProductType) = 0;

	/* 设置 ca 路径
       caPath: ca 路径
       返回值: == 0 设置成功
              != 0 设置失败
    */
    virtual int SetCaPath(char *caPath) = 0;
    /*
      获取License信息
      返回值: 0 当前存在有效License, pLicenseInfo携带License的详细信息
      范围值: 非0 当前没有有效License
    */
    virtual int GetLicenseInfo(stLocalConfig *pLicenseInfo) = 0;


    /*
        遍历Typhoon实例下所有的连接
        cb: 遍历回调函数
        userdata:用户自定义数据, 作为cb的第3个参数
    */
    virtual void TraverseConnections(Typhoon_TraverseConnections_Cb cb, void *userdata) = 0;

    /*
        需要放到Typhoon线程同步执行指定的回调函数, 并返回执行结果
        cb: 同步执行的回调函数
        userdata:用户自定义数据, 作为cb的输入参数
    */
    virtual int SynchronizedExecute(Typhoon_SynchronizedExecute_Cb cb, void *userdata) = 0;

    /*
        禁用UDP socket的checksum功能, 仅Linux系统有效
        禁用checksum的作用: 用于部分场景(比如负载均衡器无法正常更新UDP报文的校验和, 导致系统丢弃UDP报文)
    */

    virtual void DisableUdpCheckSum() = 0;


    /*
        设置socks5代理
        参数:
        stTyphoonSocks5Config *pCfg: 当输入空指针时, 清除socks5设置
        当输入有效指针时, 设置socks5设置
        Typhoon传输库不校验输入内容是否正确, 由调用方保证

        返回值:
        设置成功时, 返回值为0;
        设置失败时, 返回值小于0;
    */

    virtual int SetSocks5ProxyConfig(stTyphoonSocks5Config *pCfg) = 0;

    /*
        读取socks5代理配置
        当未设置socks5配置时, 返回NULL
        当设置了socks5配置时, 返回配置指针
    */
    virtual stTyphoonSocks5Config * GetSocks5ProxyConfig() = 0;
	/*
		获取版本号
	*/
    static char *Typhoon_GetVersion();

	virtual void SetRemainingFlow(const int64_t remainingFlow) = 0;

	virtual int StartWebServer(const char *pServerAddr, int serverPort) = 0;

	virtual uint64_t GetNanoSecond() = 0;
    virtual ~ITyphoon(){}
};



/* 创建Typhoon实例 */
TYPHOON_API ITyphoon* CreateTyphoon(const char *pLicensePath, const char *pLicenseAddr, int licensePort, int logId);

/* 释放Typhoon实例 */
TYPHOON_API void DestroyTyphoon(ITyphoon *pInstance);

/* 获得Typhoon全局配置信息 */
TYPHOON_API ITyphoonCfg* GetTyphoonCfg();

/* 将Typhoon全局配置信息输出到日志中 */
void ShowTyphoonCfg();


/* 将Typhoon的通信设置为使用SDN网络模式,       必须在CreateTyphoon前调用    */
TYPHOON_API void TyphoonUseSDN();

/* 设置SDN网络的配置文件存放路径,必须在CreateTyphoon前调用  */
TYPHOON_API int TyphoonSetSDNDataDirestory(char *path);

/* 设置SDN节点与外部通信的端口, 默认值为32002, 如果需要调用设置, 必须在CreateTyphoon前调用 */
TYPHOON_API void TyphoonSetSDNPort(uint32_t port);

/* 获取Typhoon是否是使用SDN网络 */
TYPHOON_API bool TyphoonIsUseSDN();

/* 功能辅助函数: 将IPV4 sockaddr_in 转换为SDNId */
TYPHOON_API uint64_t TyphoonAddr2ZtsId(const struct sockaddr_in *addr);

/* 功能辅助函数: 将SDNId转换为IPV4 sockaddr_in */
TYPHOON_API void TyphoonZtsId2Addr(uint64_t id, struct sockaddr_in *addr);

/* 功能辅助函数: 将SDNId转换为ip, port */
TYPHOON_API void TyphoonSDNId2IpPort(char * ztsid, char *ipv4, int ipv4_len, short *port);

/* 使用SDN网络时, 在CreateTyphoon后, 获取本节点的SDN NodeId */
TYPHOON_API uint64_t TyphoonGetNodeId();


TYPHOON_API void TyphoonGlobalInit(int clockInterval, int ackInterval=10, int ackCount=800);








#undef TYPHOON_API

#endif
