#ifndef __TYPHOON_SOCKS_H__
#define __TYPHOON_SOCKS_H__

#ifdef __cplusplus
extern "C" 
{
#endif

#include "stdint.h"

#ifdef _WIN32
#ifdef TYPHOON_SOCKS_DLL_IMPLEMENT
#define TYPHOON_SOCKS_EXTERN __declspec(dllexport)
#else 
#ifdef _STATIC_LIB_
#define TYPHOON_SOCKS_EXTERN 
#else
#define TYPHOON_SOCKS_EXTERN __declspec(dllimport) 
#endif
#endif
#define TYPHOON_STDCALL __stdcall
#else
#define TYPHOON_SOCKS_EXTERN /* nothing */
#define TYPHOON_STDCALL
#endif
typedef void * HTyphoonHandle;

enum TyphoonMultiProxyServiceType
{
	SOCKS5_SERVICE = 0,
	HTTP_SERVICE,
};

/*
 * 连接回调
 * status 为0:连接成功
 * status 非0:连接失败，失败后客户端会继续尝试重连
 */
typedef void (TYPHOON_STDCALL *TyphoonMultiProxy_OnConnected)(HTyphoonHandle pyHandle, int status);

/*
 * 连接断开回调
 */
typedef void (TYPHOON_STDCALL *TyphoonMultiProxy_OnDisconnected)(HTyphoonHandle pyHandle);

/*
 * 授权改变回调
 */
typedef void (TYPHOON_STDCALL *TyphoonMultiProxy_OnAuthChange)(HTyphoonHandle pyHandle);

/*
 * sdn连接路径改变回调
 */
typedef void (TYPHOON_STDCALL *TyphoonMultiProxy_OnSDNRouteChange)(HTyphoonHandle pyHandle, int type);

/*
 * 服务空闲回调回调
 */
typedef void (TYPHOON_STDCALL *TyphoonMultiProxy_OnServiceIdleTimeout)(HTyphoonHandle pyHandle, enum TyphoonMultiProxyServiceType serviceType);

/*
 * TyphoonProxy local与Server连接状态通知回调
 * 应用如果关心连接状态信息, 需注册对应回调函数;
 */
typedef struct TyphoonMultiProxyConnectionStatusCb
{
    TyphoonMultiProxy_OnConnected     pfnOnConnected;
    TyphoonMultiProxy_OnDisconnected  pfnOnDisConnected;
    TyphoonMultiProxy_OnAuthChange  pfnOnAuthChange;
	TyphoonMultiProxy_OnSDNRouteChange pfnOnSDNRouteChange;
	TyphoonMultiProxy_OnServiceIdleTimeout pfnOnServiceIdleTimeout;
}stTyphoonMultiProxyConnectionStatusCb;

typedef struct ConnectExParam_s{
	char *socks5Ip;
	int socks5Port;
	char *serverIp;
	int serverPort;
	unsigned int mss;
	int bCompress;
	unsigned int timeOut;
	uint8_t transferMode;
}ConnectExParam_t;

/*
 * 设置Typhoon 回调
 */
TYPHOON_SOCKS_EXTERN void TyphoonMultiProxy_SetConnectionStatusCb(stTyphoonMultiProxyConnectionStatusCb Cb);

/*
 * 获取Typhoon 回调
 */
TYPHOON_SOCKS_EXTERN stTyphoonMultiProxyConnectionStatusCb TyphoonMultiProxy_GetConnectionStatusCb();

/*
 * 初始化Typhoon
 * 参数：
 * maxSpeed:最大速度，单位KB，只能在权限范围内设置，设为0，使用最大权限速度
 * minSpeed:最小速度，单位KB，设为0，默认128KB
 * pLogPath:日志路径
 * pLicensePath:license文件产生路径
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_InitClient(unsigned int maxSpeed, unsigned int minSpeed, const char *pLogPath, const char *pLicensePath, void *rootsData, int rootsDataLen);

/*
 * 初始化Typhoon
 * 参数：
 * maxSpeed:最大速度，单位KB，只能在权限范围内设置，设为0，使用最大权限速度
 * minSpeed:最小速度，单位KB，设为0，默认128KB
 * pLogPath:日志路径
 * pLicensePath:license文件产生路径
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_InitClientEx(unsigned int maxSpeed, unsigned int minSpeed, const char *pLogPath, const char *pLicensePath, uint8_t transferMode);

/*
 * 新建一条连接
 * 参数：
 * socks5Ip:socket5 监听ip
 * socks5Port:socket5 监听端口，设置为0由系统随机分配端口
 * serverIp:Typhoon server ip
 * serverPort:Typhoon server 端口
 * mss:最大报文长度，范围 600-1442
 * 该值的实际大小由 server与client协商决定，谁小用谁
 * 
 * bCompress:是否开启压缩，1开启，0关闭;
 * 是否开启压缩实际效果由 server与client协商决定，只有都打开压缩才会有效
 * 
 * timeOut:连接超时时间，单位 ms，设置为0不使用超时
 * 返回值：
 * 返回连接的句柄，该句柄需要由调用者自行维护，其他与连接相关的api都需要此句柄
 */
TYPHOON_SOCKS_EXTERN HTyphoonHandle TyphoonMultiProxy_CreateNewConnect(const char *socks5Ip, int socks5Port, 
		const char *serverIp, int serverPort, unsigned int mss, int bCompress, unsigned int timeOut);

TYPHOON_SOCKS_EXTERN HTyphoonHandle TyphoonMultiProxy_CreateNewConnectEx(ConnectExParam_t *connP);

TYPHOON_SOCKS_EXTERN HTyphoonHandle TyphoonMultiProxy_CreateNewTyphoonConn(const char *serverIp, int serverPort, 
		unsigned int mss, int bCompress, unsigned int timeOut, uint8_t transferMode);

TYPHOON_SOCKS_EXTERN HTyphoonHandle TyphoonMultiProxy_CreateNewTyphoonConnVia(const char *serverIp, int serverPort, 
		unsigned int mss, int bCompress, unsigned int timeOut, uint8_t transferMode, uint64_t via);

/*
 * 关闭连接
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CloseConnect(HTyphoonHandle pyHandle);

/*
 * 重置连接
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 0成功，非0失败
 * 说明：
 * 该方法主要用来在mss或者压缩状态改变时候使用
 * 设置后所有的 socket5连接都会断开
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_RestartConnect(HTyphoonHandle pyHandle);

/*
 * 使能压缩
 * 参数：
 * pyHandle:连接句柄
 * 说明：
 * 该方法设置后需要重置连接才会生效
 */
TYPHOON_SOCKS_EXTERN void TyphoonMultiProxy_EnableCompress(HTyphoonHandle pyHandle);

/*
 * 关闭压缩
 * 参数：
 * pyHandle:连接句柄
 * 说明：
 * 该方法设置后需要重置连接才会生效
 */
TYPHOON_SOCKS_EXTERN void TyphoonMultiProxy_DisableCompress(HTyphoonHandle pyHandle);

/*
 * 获取连接的压缩状态
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 1开启压缩，0未开启
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_IsCompressEnabled(HTyphoonHandle pyHandle);

/*
 * 获取连接状态
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 1已连接，0未连接
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetConnectionStatus(HTyphoonHandle pyHandle);

/*
 * 获取Socks5端口
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为监听的端口
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetSocks5Port(HTyphoonHandle pyHandle);

/*
 * 获取Http端口
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为监听的端口
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetHttpPort(HTyphoonHandle pyHandle);

/*
 * 设置连接接收速度
 * 参数：
 * pyHandle:连接句柄
 * RecvSpeed:接收速度，单位KB，设为0使用最大权限带宽
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetConnRecvSpeed(HTyphoonHandle pyHandle, unsigned int RecvSpeed);

/*
 * 设置最大发送速度
 * 参数：
 * pyHandle:连接句柄
 * Speed:发送速度，单位KB，设为0使用最大权限带宽
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetMaxSendSpeed(HTyphoonHandle pyHandle, unsigned int Speed);

/*
 * 设置最小发送速度
 * 参数：
 * pyHandle:连接句柄
 * Speed:发送速度，单位KB，设为0默认128KB
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetMinSendSpeed(HTyphoonHandle pyHandle, unsigned int Speed);

/*
 * 设置连接的超时时间
 * 参数：
 * pyHandle:连接句柄
 * timeout:超时时间，单位 ms
 * 返回值:
 * 小于0失败，大于等于0为设置的超时时间
 */
TYPHOON_SOCKS_EXTERN unsigned int TyphoonMultiProxy_SetTcpIdleTimout(HTyphoonHandle pyHandle, unsigned int timeout);

/*
 * 设置服务的超时时间
 * 参数：
 * pyHandle:连接句柄
 * serviceType:服务类型
 * timeout:超时时间，单位 ms，必须大于等于 10*1000
 * 返回值:
 * 小于0失败，等于0成功
 */
TYPHOON_SOCKS_EXTERN unsigned int TyphoonMultiProxy_SetServiceIdleTimout(HTyphoonHandle pyHandle, enum TyphoonMultiProxyServiceType serviceType, unsigned int timeout);

/*
 * 获取连接的 rtt
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于0失败，大于等于0为rtt
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetConnectionRTT(HTyphoonHandle pyHandle);

/*
 * 获取连接的丢包率
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于0失败，大于等于0为丢包率
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetConnectionDropRate(HTyphoonHandle pyHandle);

/*
 * 获取Typhoon client版本
 * 参数：
 * verbuff:版本缓存，需要大于256字节
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetClientVersion(char *verbuff);

/*
 * 获取最大权限带宽
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于0失败，大于0权限带宽，单位Mbps
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetMaxAuthSendSpeed(HTyphoonHandle pyHandle);

/*
 * 设置 mss
 * 参数：
 * pyHandle:连接句柄
 * mss:范围600-1442
 * 返回值:
 * 0成功，非0失败
 * 说明：
 * 该方法设置后需要重置连接才会生效
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetMss(HTyphoonHandle pyHandle, unsigned int mss);

/*
 * 获取 mss
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为mss
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetMss(HTyphoonHandle pyHandle);

/*
 * 设置用户的私有数据，用来保存用户数据指针
 * 参数：
 * 无
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetUserData(uint64_t Data);

/*
 * 获取用户的私有数据
 * 参数：
 * 无
 * 返回值:
 * 返回用户指针
 */
TYPHOON_SOCKS_EXTERN uint64_t TyphoonMultiProxy_GetUserData();

/*
 * 获取连接的出口ip地址
 * 参数：
 * pyHandle:连接句柄
 * addr:保存地址结构体指针
 * 返回值:
 * 无
 */
TYPHOON_SOCKS_EXTERN void TyphoonMultiProxy_GetWanAddr(HTyphoonHandle pyHandle, struct sockaddr *addr);

/*
 * 获取对端ip地址
 * 参数：
 * pyHandle:连接句柄
 * addr:保存地址结构体指针
 * 返回值:
 * 无
 */
TYPHOON_SOCKS_EXTERN void TyphoonMultiProxy_GetRemoteAddr(HTyphoonHandle pyHandle, struct sockaddr *addr);

/*
 * 获取对端 rtt
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为rtt
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetQueryPeerRTT(HTyphoonHandle pyHandle);

/*
 * 获取对端丢包率
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为丢包率，单位万分之一
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetQueryPeerDropRate(HTyphoonHandle pyHandle);

/*
 * 获取最大发送速度
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为最大发送速度，单位B
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetMaxSendSpeed(HTyphoonHandle pyHandle);

/*
 * 获取最小发送速度
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为最小发送速度，单位B
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetMinSendSpeed(HTyphoonHandle pyHandle);

/*
 * 获取对端 mss
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为 mss
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetQueryMss(HTyphoonHandle pyHandle);

/*
 * 获取当前发送的实时速度
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 小于等于0失败，大于0为实时发送速度
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_GetCurSendSpeed(HTyphoonHandle pyHandle);

/*
 * 设置HSM模式
 * 参数：
 * mode:1开始HSM，0关闭HSM
 * 返回值:
 * 0成功，非0失败
 * 说明：
 * 该方法需要在TyphoonMultiProxy_InitClient之后，CreateNewConnect之前设置
 */
TYPHOON_SOCKS_EXTERN unsigned int TyphoonMultiProxy_SetHighSpeedMode(unsigned int mode);

/*
 * 设置连接的私有数据，用来保存用户数据指针
 * 参数：
 * pyHandle:连接句柄
 * Data:数据指针
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetConnectUserData(HTyphoonHandle pyHandle, uint64_t Data);

/*
 * 获取连接的私有数据
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 返回用户指针
 */
TYPHOON_SOCKS_EXTERN uint64_t TyphoonMultiProxy_GetConnectUserData(HTyphoonHandle pyHandle);

/*
 * 设置socks5 代理的配置
 * 参数：
 * server:socks5域名或ip
 * port:端口
 * username:用户名
 * password:密码
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetSocks5ProxyConfig(char *server, uint16_t port, char *username, char *password);

/*
 * 使能GSO
 * 参数：无
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_EnableGSO();

/*
 * 关闭GSO
 * 参数：无
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_DisableGSO();

/*
 * 创建 http 服务
 * 参数：
 * pyHandle:连接句柄
 * httpIp:ip地址
 * httpPort: 端口
 * timeOut:超时时间
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CreateHttpService(HTyphoonHandle pyHandle, const char *httpIp, int httpPort, uint32_t timeOut, uint16_t ifUseFirewall, uint16_t fecPercent);

/*
 * 创建端口前转服务
 * 参数：
 * pyHandle:连接句柄
 * localIp:本地地址
 * localPort: 本地端口
 * remoteIp:远端地址
 * remotePort: 远端端口
 * timeOut:超时时间
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CreateLocalPortForwardService(HTyphoonHandle pyHandle, const char *localIp, int localPort, const char *remoteIp, int remotePort, uint32_t timeOut);

/*
 * 设置传输模式
 * 参数：
 * pyHandle:连接句柄
 * TransferMode:设置连接的传输模式，0代表文件传输模式, 1代表实时传输模式
 * 返回值:
 * 设置的模式数值
 * 说明：
 * 该方法设置后需要重置连接才会生效
 */
TYPHOON_SOCKS_EXTERN uint8_t TyphoonMultiProxy_SetTransferMode(HTyphoonHandle pyHandle, uint8_t TransferMode);

/*
 * 创建远端socks5 代理
 * 参数：
 * pyHandle:连接句柄
 * pServerIp:远端监听的ip地址
 * serverPort:远端监听的端口
 * 返回值:
 * 小于等于0失败
 * 大于0成功
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CreateRemoteSocketService(HTyphoonHandle pyHandle, const char *pServerIp, uint16_t serverPort);

/*
 * 创建远端http 代理
 * 参数：
 * pyHandle:连接句柄
 * pServerIp:远端监听的ip地址
 * serverPort:远端监听的端口
 * 返回值:
 * 小于等于0失败
 * 大于0成功
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CreateRemoteHttpService(HTyphoonHandle pyHandle, const char *pServerIp, uint16_t serverPort);

/*
 * 创建远端端口前转
 * 参数：
 * pyHandle:连接句柄
 * pLocalIp:本地连接的ip地址
 * localPort:本地连接的端口
 * pServerIp:远端监听的ip地址
 * serverPort:远端监听的端口
 * 返回值:
 * 小于等于0失败
 * 大于0成功
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CreateRemotePortForwardService(HTyphoonHandle pyHandle, 
	const char *pLocalIp, uint16_t localPort, const char *pServerIp, uint16_t serverPort);

/*
 * 获取SDN ID
 * 参数：
 * 无
 * 返回值:
 * nodeId
 */
TYPHOON_SOCKS_EXTERN uint64_t TyphoonMultiProxy_GetSdnNodeId();

/*
 * sdnId 转换为 ip 和 端口
 * 参数：
 * ztsid:sdnId
 * ipv4:转换的ip地址
 * port:端口
 * 返回值:
 * 无
 */
TYPHOON_SOCKS_EXTERN void TyphoonMultiProxy_SDNId2IpPort(char * ztsid, char *ipv4, short *port);

/*
 * 设置 http 服务的 fec 百分比
 * 参数：
 * pyHandle:连接句柄
 * fecPercent:fec百分比，单位万分之一
 * 返回值:
 * 不等于0失败
 * 等于0成功
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_SetHttpServiceFecPercent(HTyphoonHandle pyHandle, uint16_t fecPercent);

/*
 * 设置http服务允许的地址
 * 参数：
 * pyHandle:连接句柄
 * ip:允许的ip地址
 * port:允许的端口
 * 返回值:
 * 非0失败
 * 等于0成功
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_AddHttpFirewallAllowAddress(HTyphoonHandle pyHandle, char* ip, int port);

/*
 * 删除http服务允许的地址
 * 参数：
 * pyHandle:连接句柄
 * ip:允许的ip地址
 * port:允许的端口
 * 返回值:
 * 非0失败
 * 等于0成功
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_DelHttpFirewallAllowAddress(HTyphoonHandle pyHandle, char* ip, int port);

/*
 * 设置多线程发送
 * 参数：
 * enable:1使能，0关闭
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN unsigned int TyphoonMultiProxy_SetMultiSender(unsigned int enable);

/*
 * 退出Typhoon
 * 参数：
 * 无
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_ExitClient();

/*
 * 关闭 Http 服务
 * 参数：
 * pyHandle:连接句柄
 * 返回值:
 * 0成功，非0失败
 */
TYPHOON_SOCKS_EXTERN int TyphoonMultiProxy_CloseHttpService(HTyphoonHandle pyHandle);


#ifdef __cplusplus
}
#endif

#endif
