#ifndef __TYPHOON_DEFINE_C__H__
#define __TYPHOON_DEFINE_C__H__


#include "uv.h"
#include "YyAuthenticationManageFile.h"

#ifdef __cplusplus
extern "C" 
{
#endif


#ifndef SOCKADDR
typedef struct sockaddr SOCKADDR;
#endif

//ChannelID 宏定义
#define TYPHOON_INVALID_CHANNEL_ID      0xffff                  //无效的channelID
#define TYPHOON_DEFAULT_CHANNEL_ID      0                       //连接创建成功后的默认channelID
#define TYPHOON_INVALID_HANDLE   0

#define CCMODE_DROPRATE                 0                       //只使用丢包率作为拥塞控制输入
#define CCMODE_RTT                      1                       //只使用RTT作为拥塞控制输入
#define CCMODE_DROPRATE_AND_RTT         2                       //使用丢包率和RTT作为拥塞控制输入
#define CCMODE_LOW_PRIORITY             3                       //低优先级流量算法

#define TYPHOON_INVALID_CCMODE          255                     //无效的CCMODE
#define MAX_HASH_KEY_LEN                32                      //hash秘钥最大长度

#define MAX_TYPHOON_HOST_LEN            128                     //host字符串最大长度
#define MAX_TYPHOON_USERNAME_LEN        128                     //用户名最大长度
#define MAX_TYPHOON_PASSWORD_LEN        128                     //用户名最大长度




typedef void * HTyphoonChannel;
typedef void * HTyphoonConn;
typedef void * HTyphoon;
typedef void * HTyPhoonConnCallBack;
typedef void * HTyphoonBuff;
typedef void * HTyphoonFecTun;
typedef void (*Typhoon_Logger)(char* str);
typedef void (*Typhoon_LevelLogger)(int level, char* str);

typedef void (*TyphonnConn_TraverseChannels_Cb_C)(HTyphoonConn Conn, HTyphoonChannel Channel, void* arg);


typedef int (*Typhoon_SynchronizedExecute_Cb)(void* arg);


typedef enum TYPHOON_ERROCODE
{
    //errocode : 0,成功，1失败超时
    TYPHOON_CON_SUCCEED = 0,
    TYPHOON_CON_TIMEOUT,
    TYPHOON_CON_BUTT,
    TYPHOON_CON_NETWORK_ERROR       // 网络异常
}enTyphoonErr;

typedef enum TYPHOON_DISCONNECT_CAUSE
{
    TYPHOON_REMOTE_DISCONNECT  = 0,
    TYPHOON_TIMEOUT_DISCONNECT = 1,
    TYPHOON_MTU_RESET          = 2,
    TYPHOON_INVALID_AK         = 3,         //不合法的客户端, 用于授权
    TYPHOON_IN_BLACKLIST       = 4,         //客户端IP在黑名单中或不在白名单中
    
    TYPHOON_DISCONNECT_BUTT
}enTyphoonDisconnectCause;


//channel断开状态码
typedef enum TYPHOON_CHANNEL_CLOSE_TYPE
{
    TYPHOON_CHANNEL_CLOSE_NORMAL = 0,           //对端主动CloseChannel导致的channel断开
    TYPHOON_CHANNEL_CLOSE_RESET,                //对端channel已经异常关闭导致的channel断开
    TYPHOON_CHANNEL_CLOSE_INFO,                 //正常shutdown后, channel进入close状态前的通知
    TYPHOON_CHANNEL_CLOSE_BUTT
}enChannelCloseType;


typedef enum TYPHOON_COMPRESS_METHOD
{
    TYPHOON_COMPRESS_NONE = 0,              //不支持压缩
    TYPHOON_COMPRESS_ZSTD = 0x01,           //支持ZSTD
    TYPHOON_COMPRESS_ZLIB = 0x02,           //支持ZLIB
    TYPHOON_COMPRESS_RESERVE2 = 0x04,       //保留值, 用于后续扩充
    TYPHOON_COMPRESS_RESERVE3 = 0x08,
    TYPHOON_COMPRESS_RESERVE4 = 0x10,
    TYPHOON_COMPRESS_RESERVE5 = 0x20,
    TYPHOON_COMPRESS_RESERVE6 = 0x40,
    TYPHOON_COMPRESS_RESERVE7 = 0x80   
}enTyphoonCompressMethod;


enum tagTYPHOON_LOGLEVEL
{
    TYPHOON_INFO = 20,
    TYPHOON_NOTICE = 40,
    TYPHOON_DEBUG = 60,     
    TYPHOON_WARN = 80,
    TYPHOON_ERROR = 100,
    TYPHOON_FATAL = 120,
    TYPHOON_BUTT
};


typedef enum TYPHOON_SDNPATH_TYPE
{
    TYPHOON_SDN_RELAY = 0,
    TYPHOON_SDN_DIRECT = 1,
    TYPHOON_SDNTYPE_BUTT
}enTyphoonSDNPathType;



typedef struct TyphoonTimerConfig
{
    int32_t TryConnectTime;
    int32_t HandShakeTime;
    int32_t ConnBrokenTime;
}stTyphoonTimerConfig;


struct TyphoonConnStats                             //1条连接的统计信息
{
    /* Rx */
    int64_t m_dwRead;                               //当前接收到的数据长度,已经确认的
    int64_t m_ReadCount;                            //当前接收到的包数,已经确认的
    int64_t m_dwDumpCount;                          //收到的重包数
    int64_t m_dwDumpSize;							//收到的重包大小
    int64_t m_dwOutRange;                           //收到的不在接收窗口中的包数
    int64_t m_dwOutRangeSize;						//收到的不在接收窗口中的包大小
    int64_t m_AppRxTraffic;							//实际接收到的应用层报文流量大小, 当数据被压缩时, 网络流量小于应用层报文原始大小
    int64_t m_RecvResendCount;						//收到的重发报文数量
    int64_t m_RecvResendSize;						//收到的重发报文数量
    int64_t m_RxFecDataSize;						//收到的Fec数据大小
	int64_t m_RxFecDataCount;						//收到的Fec报文数量
    int64_t m_RxFecRecoverDataSize;					//通过FEC恢复出的数据数量
	int64_t m_RxFecRecoverDataCount;				//通过FEC恢复出的数据个数
	int64_t m_RxErrorFecCount;						//Fec解码错误次数统计
	int64_t m_RxFecOutRangeCount;					//Fec解码成功后, 恢复的数据不在接收窗口内次数统计
	int64_t m_RxFecDumpCount;						//Fec解码成功后, 恢复的数据已经收到重复次数统计
	int64_t m_RxFecNoDecoderpCount;					//Fec原始数据, 无法找到Decoder的统计(原因为FecRecover报文丢失了)
	int64_t	m_RxDelayedDataCount;					//数据的部分报文由于丢失重传, 比未丢失报文的数据达到时间要晚的数量

    
    /* Tx */
    int64_t m_dwWrite;                            	//当前接发送的数据长度,已经确认的
    int64_t m_Checked;                            	//已经确认的包数, ACK+SACK  
    int64_t m_SendTotalCount;                     	//总共发送的总包数,包括重传部分
    int64_t m_ReSendCount;                        	//快速重传的包数
    int32_t m_rtt;                                	//连接的RTT
    int32_t m_minrtt;                             	//连接的最小RTT
    int64_t m_AppTxTraffic;						  	//记录应用层Send接口的数据流量大小
    int64_t m_TxFecDataSize;					  	//发出的Fec数据大小
	int64_t m_TxFecDataCount;						//发出的Fec报文数量 
	int32_t m_TxDropCount;							//模拟丢包功能丢失的报文数量
    
};



typedef struct  TyphoonCfg
{
    Typhoon_Logger Log;                     //Typhoon内部日志输出接口, 如果不设置则无日志输出
    Typhoon_LevelLogger pfnLevelLogger;     //Typhoon内部日志输出接口, 如果不设置则无日志输出
    uint32_t UdpSocketSendBuffSize;         //Typhoon实例的UDP socket发送缓存大小, 1个Typhoon实例绑定1个UDP socket, 由该实例所有连接共用;
                                            //默认值为1MB, 发送缓冲区大小建议不小于1MB
    uint32_t UdpSocketRecvBuffSize;         //Typhoon实例的UDP socket接收缓存大小, 1个Typhoon实例绑定1个UDP socket, 由该实例所有连接共用;
                                            //默认值为1MB, 接收缓冲区大小建议不小于1MB
    uint16_t PackCountTriggerAck;           //收到多少个数据报文触发一次ACK, 默认为250个
    uint8_t  LoopInterval;                  //Typhoon内部调度间隔, 默认为10毫秒
    uint8_t  AckInterval;                   //客户端最大ACK响应间隔时间, 默认为50毫秒
    uint8_t  NoLockMode;                    //如果Typhoon应用与Typhoon协议栈运行在同一个线程中, 此处设置为1, 双方的数据传递可以不使用锁
                                            //默认为0, 即双方的数据传递会使用锁
	uint8_t	HightSpeedMode;                 //是否为HightSpeedMode, 默认为0
    uint8_t CCMode;                         //拥塞控制模式. 0使用丢包率, 1使用RTT, 2使用丢包率+时延
    uint16_t ResistDropRate;                //可抵抗的丢包率. 这里使用万分制比列表示, 默认为250, 即万分之250 --> 2.5%
    uint8_t IOThreadNum;                    //Typhoon Socket I/O线程数量, 默认为1, 最大可以设置为2
    uint8_t ResendCheckTime;                //在进行报文重发时, 需要确认报文上次发送时间到重发时是否大于RTT+1个缓冲时间, 默认值为10毫秒
    uint8_t UdpGSO;                         //是否启用UDP GSO, UDP GSO在Linux内核4.18后才支持CentOS 8.0支持
    uint8_t BindCpu;                        //是否启用CPU绑定, 默认为0不启用
	uint32_t LogLevel;                       //日志输出级别, 只有大于指定级别才输出日志, 默认为DEBUG(60)
	
}stTyphoonCfg;                              



typedef struct TyphoonConnCfg                
{
    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;        //配置当前连接是否使用额外的线程执行用户数据通知回调, 默认为1, 即使用
                                           //取值范围[0, 1]
    uint8_t  CompressMethod;               //连接支持的压缩方法, 可以设置为支持1种或多种方法, 通过enTyphoonCompressMethod的值 | 得到结果                                           
    uint8_t  TransferMode;                 //连接传输模式, 分为文件传输模式0, 实时传输模式1, 默认为0
    uint8_t  UseDataPush;				    //取值范围[0, 1]: 1 PushData, 0 PullData. 当数据达到时, PushData的方式是调用OnRead回调, 非PushData(PullData)的方式是调用OnDataArrived回调
    										//两种方式没有本质区别, 区别在于OnRead回调让用户必须立刻马上处理这个数据, 而OnDataArrived只是通知用户数据达到了, 用户可以选择马上处理或者不马上处理
}stTyphoonConnCfg;


typedef struct TyphoonProxyLicense{
	uint8_t  version;
	uint16_t clientNum;			  //允许接入的客户端数量，0表示无限制
	uint16_t clientLicenseLevel;  //允许接入的客户端的带宽，单位Mbps，0表示无限制
	uint32_t flow;				  //流量，包括上行和下行流量，单位G，0表示无限制
}sTyphoonProxyLicense;


typedef int32_t (*Typhoon_AppInit_Callback)();
typedef void (*Typhoon_AppUninit_Callback)();

typedef void (*TyphoonConn_OnConnected)(HTyphoonConn pConn, enTyphoonErr erro, uint8_t *data, uint16_t data_len);
typedef void (*TyphoonConn_OnDisconnected)(HTyphoonConn pConn, enTyphoonDisconnectCause cause);
typedef void (*TyphoonConn_OnRead)(HTyphoonConn pConn, HTyphoonChannel pChan,uint8_t* pData,int32_t len);
typedef void (*TyphoonConn_OnWritable)(HTyphoonConn pConn, HTyphoonChannel pChan);
typedef void (*TyphoonConn_OnSentDataAcknowledged)(HTyphoonConn pConn, HTyphoonChannel pChan, int32_t ackLen);
typedef void (*TyphoonConn_OnDataArriveNotify)(HTyphoonConn pConn, HTyphoonChannel pChan);
typedef void (*TyphoonConn_OnChannelOpen)(HTyphoonConn pConn, HTyphoonChannel pChan);
typedef void (*TyphoonConn_OnChannelClose)(HTyphoonConn pConn, HTyphoonChannel pChan, enChannelCloseType closeType);
typedef void (*TyphoonConn_OnAuthChange)(HTyphoonConn pConn, sTyphoonProxyLicense *license);
typedef void (*TyphoonConn_OnFecTunOpen)(HTyphoonConn pConn, HTyphoonFecTun pTun);
typedef void (*TyphoonConn_OnFecTunClose)(HTyphoonConn pConn, HTyphoonFecTun pTun);
typedef uint32_t (*TyphoonConn_OnTimer)(HTyphoonConn pConn);
typedef void (*TyphoonConn_OnSDNRouteChange)(HTyphoonConn pConn, enTyphoonSDNPathType type);




typedef struct __TyPhoonConnCallBack
{
    TyphoonConn_OnConnected pfnOnConnected;
    TyphoonConn_OnDisconnected pfnOnDisconnected;
    TyphoonConn_OnRead  pfnOnRead;
    TyphoonConn_OnWritable pfnWritable;
    TyphoonConn_OnSentDataAcknowledged pfnOnSentDataAcknowledged;
    TyphoonConn_OnDataArriveNotify pfnOnDataArriveNotify; 
    TyphoonConn_OnChannelOpen  pfnOnChannelOpen;
    TyphoonConn_OnChannelClose pfnOnChannelClose;
    TyphoonConn_OnAuthChange pfnOnAuthChange;
	TyphoonConn_OnTimer		  pfnOnTimer;
	TyphoonConn_OnSDNRouteChange pfnOnSDNRouteChange;
}stTyPhoonConnCallBack;


typedef struct __Socks5Config
{
    char server[MAX_TYPHOON_HOST_LEN];          //代理服务器ip或域名
    uint16_t port;                              //代理服务器端口
    char username[MAX_TYPHOON_USERNAME_LEN];    //代理服务器用户名
    char password[MAX_TYPHOON_PASSWORD_LEN];    //代理服务器密码
}stTyphoonSocks5Config;

#ifdef __cplusplus
}
#endif

#endif

