#ifndef __TYPHOON_C__H__
#define __TYPHOON_C__H__

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

#ifdef __cplusplus
extern "C" 
{
#endif


#ifdef _WIN32
#ifdef DLL_IMPLEMENT
#define TYPHOON_EXTERN __declspec(dllexport)
#else 
#define TYPHOON_EXTERN __declspec(dllimport) 
#endif
#else
#define TYPHOON_EXTERN /* nothing */
#endif

/* TyPhoonConnCallBack 函数 */
TYPHOON_EXTERN HTyPhoonConnCallBack CreateHTyPhoonConnCallBack(stTyPhoonConnCallBack *pCb);
TYPHOON_EXTERN void DestroyHTyPhoonConnCallBack(HTyPhoonConnCallBack handle);
TYPHOON_EXTERN void TyPhoonConnCallBack_SetPushData(HTyPhoonConnCallBack handle, int set);
TYPHOON_EXTERN int TyPhoonConnCallBack_GetPushData();


/* TyphoonChannel 相关函数 */
TYPHOON_EXTERN int32_t TyphoonChannel_IsWritable(HTyphoonChannel handle);
TYPHOON_EXTERN int32_t TyphoonChannel_Send(HTyphoonChannel handle, uint8_t* pData,int32_t len);
TYPHOON_EXTERN int32_t TyphoonChannel_CompressSend(HTyphoonChannel handle, uint8_t* pData,int32_t len, uint8_t compressLevel);
TYPHOON_EXTERN int32_t TyphoonChannel_SendWithExpiredTime(HTyphoonChannel handle, uint8_t* pData,int32_t len, uint32_t lifeTime);
TYPHOON_EXTERN int32_t TyphoonChannel_SendWithMaxCount(HTyphoonChannel handle, uint8_t* pData,int32_t len, uint8_t maxCount);
TYPHOON_EXTERN int32_t TyphoonChannel_SendWithAllFunction(HTyphoonChannel handle, 
														   uint8_t* pData, 
														   int32_t len, 
														   uint8_t compresLevel, 
														   uint32_t lifeTime, 
														   uint8_t maxSendCount, 
														   uint16_t fecPercent);


TYPHOON_EXTERN HTyphoonBuff TyphoonChannel_Recv(HTyphoonChannel handle);
TYPHOON_EXTERN int32_t TyphoonChannel_Close(HTyphoonChannel handle);
TYPHOON_EXTERN int32_t TyphoonChannel_Shutdown(HTyphoonChannel handle);
TYPHOON_EXTERN void TyphoonChannel_SetUserData(HTyphoonChannel handle, uint64_t Data);
TYPHOON_EXTERN uint64_t TyphoonChannel_GetUserData(HTyphoonChannel handle);
TYPHOON_EXTERN void TyphoonChannel_EnableWritableWatch(HTyphoonChannel handle);
TYPHOON_EXTERN void TyphoonChannel_DisableWritableWatch(HTyphoonChannel handle);
TYPHOON_EXTERN uint8_t TyphoonChannel_GetWritableWatch(HTyphoonChannel handle);
TYPHOON_EXTERN uint8_t TyphoonChannel_GetWritableWatch(HTyphoonChannel handle);
TYPHOON_EXTERN int64_t TyphoonChannel_GetUnackedDataLength(HTyphoonChannel handle);
TYPHOON_EXTERN uint16_t TyphoonChannel_ChannelId(HTyphoonChannel handle);
TYPHOON_EXTERN void TyphoonChannel_ShowChannel(HTyphoonChannel handle);
TYPHOON_EXTERN int TyphoonChannel_OpenByClient(HTyphoonChannel handle);
TYPHOON_EXTERN int TyphoonChannel_OpenByServer(HTyphoonChannel handle);
TYPHOON_EXTERN int TyphoonChannel_OpenBySelf(HTyphoonChannel handle);


/* TyphoonFecTun 函数 */
TYPHOON_EXTERN int32_t TyphoonFecTun_Close(HTyphoonFecTun Tun);
TYPHOON_EXTERN uint16_t TyphoonFecTun_TunnelId(HTyphoonFecTun Tun);



/* TyphoonConn 函数 */
TYPHOON_EXTERN HTyphoonConn CreateHTyphoonConn(HTyphoon handle);
TYPHOON_EXTERN void DestroyHTyphoonConn(HTyphoonConn handle);
TYPHOON_EXTERN int32_t TyphoonConn_ConnectTo(HTyphoonConn handle, char *ip, uint16_t port, int sync, uint8_t *data, uint16_t data_len);
TYPHOON_EXTERN int32_t TyphoonConn_ConnectToEx(HTyphoonConn handle, char *ip, uint16_t port, char *bind_ip, uint16_t bind_port,int sync, uint8_t *data, uint16_t data_len);
TYPHOON_EXTERN int32_t TyphoonConn_IsConnected(HTyphoonConn handle);
TYPHOON_EXTERN HTyphoonChannel TyphoonConn_OpenChannel(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetTimeout(HTyphoonConn handle, stTyphoonTimerConfig *pCfg);
TYPHOON_EXTERN stTyphoonTimerConfig TyphoonConn_GetTimeout(HTyphoonConn handle);
TYPHOON_EXTERN uint16_t TyphoonConn_QueryChannelCount(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetMaxSegmentSize(HTyphoonConn handle, uint16_t Mss);
TYPHOON_EXTERN uint16_t TyphoonConn_GetMaxSegmentSize(HTyphoonConn handle);
TYPHOON_EXTERN uint16_t TyphoonConn_QueryMaxSegmentSize(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetUserData(HTyphoonConn handle, uint64_t Data);
TYPHOON_EXTERN uint64_t TyphoonConn_GetUserData(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetSendBuffSize(HTyphoonConn handle, uint32_t Size);
TYPHOON_EXTERN uint32_t TyphoonConn_GetSendBuffSize(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetRecvBuffSize(HTyphoonConn handle, uint32_t Size);
TYPHOON_EXTERN uint32_t TyphoonConn_GetRecvBuffSize(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetConnCallback(HTyphoonConn handle, HTyPhoonConnCallBack cb);
TYPHOON_EXTERN HTyPhoonConnCallBack TyphoonConn_GetConnCallback(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetFixedSendSpeed(HTyphoonConn handle, uint32_t Size);
TYPHOON_EXTERN uint32_t TyphoonConn_GetFixedSendSpeed(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetMaxSendSpeed(HTyphoonConn handle, uint32_t Size);
TYPHOON_EXTERN uint32_t TyphoonConn_GetMaxSendSpeed(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetMinSendSpeed(HTyphoonConn handle, uint32_t Size);
TYPHOON_EXTERN uint32_t TyphoonConn_GetMinSendSpeed(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_TraverseChannels(HTyphoonConn handle, TyphonnConn_TraverseChannels_Cb_C traverse_cb, void* arg);
TYPHOON_EXTERN uint32_t TyphoonConn_QueryRTT(HTyphoonConn handle);
TYPHOON_EXTERN uint32_t TyphoonConn_QueryDropRate(HTyphoonConn handle);
TYPHOON_EXTERN HTyphoonChannel TyphoonConn_GetDefaultChannel(HTyphoonConn handle);
TYPHOON_EXTERN int32_t TyphoonConn_GetMaxAuthSendSpeed(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetCompress(HTyphoonConn handle, uint8_t CompressMethod);
TYPHOON_EXTERN uint32_t TyphoonConn_GetCompress(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetAuth(HTyphoonConn handle, sTyphoonProxyLicense  *license);
TYPHOON_EXTERN HTyphoonChannel TyphoonConn_GetChannel(HTyphoonConn handle, uint16_t cid);
TYPHOON_EXTERN uint32_t TyphoonConn_QueryPeerRTT(HTyphoonConn handle);
TYPHOON_EXTERN uint32_t TyphoonConn_QueryPeerDropRate(HTyphoonConn handle);
TYPHOON_EXTERN TyphoonConnStats *TyphoonConn_GetStats(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_GetWanAddr(HTyphoonConn handle, struct sockaddr *addr);
TYPHOON_EXTERN void TyphoonConn_GetRemoteAddr(HTyphoonConn handle, struct sockaddr *addr);
TYPHOON_EXTERN uint32_t TyphoonConn_GetCurSendSpeed(HTyphoonConn handle);
TYPHOON_EXTERN int TyphoonConn_IsClient(HTyphoonConn handle);
TYPHOON_EXTERN int TyphoonConn_IsServer(HTyphoonConn handle);
TYPHOON_EXTERN uint8_t TyphoonConn_GetTransferMode(HTyphoonConn handle);
TYPHOON_EXTERN uint8_t TyphoonConn_SetTransferMode(HTyphoonConn handle);
TYPHOON_EXTERN void TyphoonConn_SetPacketLoss(HTyphoonConn handle, uint16_t percent);
TYPHOON_EXTERN int TyphoonConn_IsPacketLossSet(HTyphoonConn handle);
TYPHOON_EXTERN int TyphoonConn_GetPacketLoss(HTyphoonConn handle);
TYPHOON_EXTERN HTyphoonFecTun TyphoonConn_OpenFecTun(HTyphoonConn handle, uint16_t channelCount);
TYPHOON_EXTERN void TyphoonConn_CloseFecTun(HTyphoonConn handle, uint16_t tunId);



/* Typhoon 函数 */
TYPHOON_EXTERN HTyphoon CreateHTyphoon(const char *pLicensePath, const char *pLicenseAddr, int licensePort, int logId);
TYPHOON_EXTERN void DestroyHTyphoon(HTyphoon handle);
TYPHOON_EXTERN int Typhoon_ActiveLicense(HTyphoon handle, char *licenseCode, int productType);
TYPHOON_EXTERN int Typhoon_StartWebServer(HTyphoon handle,  const char *pServerAddr, int serverPort);
TYPHOON_EXTERN int Typhoon_GetLicenseInfo(HTyphoon handle, stLocalConfig *pLicenseInfo);
TYPHOON_EXTERN void Typhoon_SetConnCallback(HTyphoon handle, HTyPhoonConnCallBack hCb);
TYPHOON_EXTERN int Typhoon_InitUDPSocket(HTyphoon handle, char* ip, uint16_t port);
TYPHOON_EXTERN SOCKADDR Typhoon_GetLocalAddr(HTyphoon handle);
TYPHOON_EXTERN int32_t Typhoon_GetConnectionCount(HTyphoon handle);
TYPHOON_EXTERN stTyphoonCfg Typhoon_GetTyphoonConfig(HTyphoon handle);
TYPHOON_EXTERN void Typhoon_SetTyphoonConfig(HTyphoon handle, stTyphoonCfg *pCfg);
TYPHOON_EXTERN stTyphoonConnCfg Typhoon_GetConnDefaultCfg(HTyphoon handle);
TYPHOON_EXTERN void Typhoon_SetConnDefaultCfg(HTyphoon handle, stTyphoonConnCfg *pCfg);
TYPHOON_EXTERN uv_loop_t *Typhoon_GetMainLoop(HTyphoon handle);
TYPHOON_EXTERN void Typhoon_SetAppInitCB(HTyphoon handle, Typhoon_AppInit_Callback Init);
TYPHOON_EXTERN void Typhoon_SetAppUninitCB(HTyphoon handle, Typhoon_AppUninit_Callback Uninit);
TYPHOON_EXTERN void Typhoon_SetConnCallback(HTyphoon handle, HTyPhoonConnCallBack hCb);
TYPHOON_EXTERN int Typhoon_SynchronizedExecute(HTyphoon handle, Typhoon_SynchronizedExecute_Cb cb, void *userdata);
TYPHOON_EXTERN char *Typhoon_GetVersion();
TYPHOON_EXTERN void Typhoon_DisableUdpCheckSum(HTyphoon handle);
TYPHOON_EXTERN int Typhoon_SetCaPath(HTyphoon handle, char *caPath);
TYPHOON_EXTERN int Typhoon_SetSocks5ProxyConfig(HTyphoon handle, stTyphoonSocks5Config *pCfg);
TYPHOON_EXTERN stTyphoonSocks5Config *Typhoon_GetSocks5ProxyConfig(HTyphoon handle);
TYPHOON_EXTERN void Typhoon_SetRemainingFlow(HTyphoon handle, const int64_t remainingFlow);
TYPHOON_EXTERN int Typhoon_SetSDNDataDirestory(char *path);
TYPHOON_EXTERN void Typhoon_SetSDNPort(uint32_t port);
TYPHOON_EXTERN TyphoonCfg* Typhoon_GetGlobalCfg();
TYPHOON_EXTERN void Typhoon_SDNId2IpPort(char * ztsid, char *ipv4, int ipv4_len, short *port);
TYPHOON_EXTERN void Typhoon_GlobalInit(int clockInterval);
TYPHOON_EXTERN void Typhoon_UseSDN();
TYPHOON_EXTERN int Typhoon_IsUseSDN();
TYPHOON_EXTERN uint64_t Typhoon_GetNodeId();


/* TyphoonBuff 函数 */
//应用无法直接Create TyphoonBuff实例, 在PULL数据的模式下, 应用可以通过连接的recv函数获取TyphoonBuff
//此处的操作仅用于获取缓存头指针/缓存数据长度
TYPHOON_EXTERN void DestroyHTyphoonBuff(HTyphoonBuff buf);
TYPHOON_EXTERN uint8_t* TyphoonBuff_GetBuff(HTyphoonBuff buf);
TYPHOON_EXTERN int32_t TyphoonBuff_GetLen(HTyphoonBuff buf);

#ifdef __cplusplus
}
#endif

#endif
