#ifndef RT_AVDEngine_C_H_
#define RT_AVDEngine_C_H_

#include "common_c.h"
#include "room_c.h"

typedef rtc::EngineOption AVDEngineOption;
/**
* AVD引擎回调接口
*
* AVD引擎回调接口定义了引擎接口操作的异步返回。
*/
typedef struct AVDEngine_Callback {
	/// 异步返回
	/** 初始化引擎操作异步返回
	*
	* @param[in] result 初始化错误代码。
	* @sa avd_engine_init
	*/
	void(*onInitResult)(Result result);
	/** 反初始化引擎操作异步返回
	*
	* @param[in] result 反初始化错误代码。
	* @sa avd_engine_uninit
	*/
	void(*onUninitResult)(Result result);
	/** 获取房间信息操作异步返回
	*
	* @param[in] callId 调用Id。
	* @param[in] result 获取房间错误代码。
	* @param[in] room 房间信息。
	*
	* @sa avd_engine_getRoomByRoomId
	* @sa avd_engine_getRoomByAppRoomId
	*/
	void(*onGetRoomResult)(uint32 callId, Result result, const AVDRoomInfo& room);
	/** 查询房间信息操作异步返回
	*
	* @param[in] callId 调用Id。
	* @param[in] result 查询房间错误代码。
	* @param[in] *rooms 房间信息列表。
	* @param[in] numOfRoom 列表长度。
	*
	* @sa avd_engine_findRooms
	*/
	void(*onFindRoomsResult)(uint32 callId, Result result, const LPAVDRoomInfo& rooms, uint32 numOfRoom);
	/** 安排房间操作异步返回
	*
	* @param[in] callId 调用Id。
	* @param[in] result 安排房间错误代码。
	* @param[in] *roomId 房间Id。
	*
	* @sa avd_engine_scheduleRoom
	*/
	void(*onScheduleRoomResult)(uint32 callId, Result result, const char* roomId);
	/** 取消房间操作异步返回
	*
	* @param[in] callId 调用Id。
	* @param[in] result 取消房间错误代码。
	* @param[in] roomId 房间Id。
	*
	* @sa avd_engine_cancelRoom
	*/
	void(*onCancelRoomResult)(uint32 callId, Result result, const char* roomId);
	/** 获取房间中参会者人数异步返回
	* @param[in] callId 调用Id。
	* @param[in] result 错误代码。
	* @param[in] usersCount 房间参会者人数。
	* @param[in] roomId 房间Id。
	* @sa getUsersCount
	*/
	void(*onGetUsersCountResult)(uint32 callId, Result result, uint32 usersCount, const char* roomId);

	/** 呼叫外部设备回调
	* @param[in] callId 调用Id。
	* @param[in] result 错误代码。
	* @param[in] userId 设备用户Id。
	* @sa callOutgoingDevice
	*/
	void(*onCallOutgoingDevice)(uint32 callId, Result result, const char* userId);

	/** 呼叫外部设备回调
	* @param[in] callId 调用Id。
	* @param[in] result 错误代码。
	* @param[in] userId 设备用户id。
	* @sa callOutgoingDevice
	*/
	void (*onCallOutgoingDeviceResult)(uint32 callId, Result result, const char* userId);
	AVDEngine_Callback() {
		onInitResult = NULL;
		onUninitResult = NULL;
		onGetRoomResult = NULL;
		onFindRoomsResult = NULL;
		onScheduleRoomResult = NULL;
		onCancelRoomResult = NULL;
		onGetUsersCountResult = NULL;
		onCallOutgoingDevice = NULL;
		onCallOutgoingDeviceResult = NULL;
	}
}*LPAVDEngine_Callback;
///
extern "C" {
	/**
	* AVD引擎接口
	*
	* AVD引擎接口定义了引擎全局初始化操作和房间安排、查询、删除等操作。
	*/

	/** 初始化引擎
	*
	* @param[in] cb 引擎回调指针。
	* @param[in] *severuri 服务器uri。
	* @param[in] *appkey 公司分发给应用公司的应用秘钥。
	* @param[in] *secretkey 公司分发给应用公司的安全秘钥。
	* @note AVD引擎在做任何功能操作前，必须先要初始化引擎成功。引擎初始化是一个异步操作，调用此接口后等待回调中函数onInitResult回调，判断是否初始化成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_init(LPAVDEngine_Callback cb, const char* severuri, const char* appkey, const char* secretkey);
	/** 初始化引擎
	*
	* @param[in] cb 引擎回调指针。
	* @param[in] severuri 服务器uri。
	* @param[in] token 认证后的凭证。
	* @note AVD引擎在做任何功能操作前，必须先要初始化引擎成功。引擎初始化是一个异步操作，调用此接口后等待回调中函数onInitResult回调，判断是否初始化成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_initWithToken(LPAVDEngine_Callback cb, const char* severuri, const char* token);
	/** 初始化引擎
	*
	* @param[in] cb 引擎回调指针。
	* @param[in] severuri 服务器uri。
	* @param[in] oemName 公司Open-AVD产品OEM的厂家名称。
	* @note AVD引擎在做任何功能操作前，必须先要初始化引擎成功。引擎初始化是一个异步操作，调用此接口后等待回调中函数onInitResult回调，判断是否初始化成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_initWithOEM(LPAVDEngine_Callback cb, const char* severuri, const char* oemName);

    //是否启用客户自己的认证token,默认为false
    RT_API_EXPORT void avd_engine_setCustomerTokenEnabled(bool enable);
	/** 反初始化引擎
	*
	* @note AVD反初始化后，引擎中涉及的所有房间对象都无效，引擎上的功能函数都无法正常使用。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_uninit();
	/** 判断引擎是否正常工作
	*
	* @return 返回引擎是否正常工作。
	*/
	RT_API_EXPORT AVDBool avd_engine_isWorking();
	/** 设置引擎日志配置
	*
	* @param[in] params 日志等级[sensitive verbose info warning error none ]，以上只可取一个值；[debug]是否在调试输出；两个值时中间空格分隔。
	* @param[in] *filename 日志文件名，若无日志文件名，则不写文件。
	*
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_setLogParams(const char* params, const char* filename);
	/** 获取引擎版本号
	*
	* @param[in] *szVersion 版本号信息。
	* @param[in] len 版本号信息长度。
	* @return 返回引擎版本号。
	*/
	RT_API_EXPORT Result avd_engine_getVersion(char* szVersion, uint32& len);
	/** 根据错误代码获取关联的错误信息描述
	* @param[in] code 错误代码。
	* @return 返回错误信息描述。	
	* @param[in] *message 错误描述。
	* @param[in] size 错误描述信息长度。
	*/
	RT_API_EXPORT Result avd_engine_getErrorMessage(Result code, char* message, uint32& size);
	/** 设置代理信息
	* @param[in] type 代理的类型. 目前支持Https代理(音视频数据以TCP发送),Socks5代理（音视频数据以UDP发送）
	* @param[in] ip 代理的IP地址
	* @param[in] port 代理的端口
	* @param[in] username 代理的认证账户(如果如认证,可传递空字符串)
	* @param[in] password 代理的认证密码(如果如认证,可传递空字符串)
	* os:
	*/
	RT_API_EXPORT void avd_engine_setProxy(AVDProxyType type, const char* ip, int port, const char* username, const char* password);
	/** 设置引擎选项
	*
	* @param[in] type 引擎选项类型。
	* @param[in] *value 引擎选项值指针。
	*
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_setOption(AVDEngineOption type, void* value);
	RT_API_EXPORT Result avd_engine_setOption2(AVDEngineOption type, const char* value);
	/** 获取引擎选项
	*
	* @param[in] type 引擎选项类型。
	* @param[out] *value 引擎选项返回值指针。
	*
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_getOption(AVDEngineOption type, void* value);
	RT_API_EXPORT Result avd_engine_getOption2(AVDEngineOption type, char* value, uint32& size);
	/** 判断是否拥有功能
	* @param[in] ft 功能枚举。
	* @return 返回是否拥有。
	*/
	RT_API_EXPORT AVDBool avd_engine_hasFunction(rtc::FunctionType ft);
	/** 获取功能集
	* @return 返回功能集。
	* @sa FunctionType
	*/
	RT_API_EXPORT uint32 avd_engine_getFunctions();
	//
	/** 查找房间信息
	*
	* @param[in,out] callId 调用Id，用于区别多次调用，在回调中会带上此调用Id，便于应用层区别每次调用；若调用时为0，内部产生一个序号。
	* @param[in] *filter 查找条件：json字符串，用房间信息结构中的字段“fieldname=value,...”来表示。
	*
	* @note 查找房间信息为异步操作，调用此接口后等待回调中函数onFindRoomsResult回调，判断是否查找成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_findRooms(uint32& callId, const char* filter /*jason: fieldname=value,... fieldname use RoomInfo */);
	/** 安排房间
	*
	* @param[in,out] callId 调用Id，用于区别多次调用，在回调中会带上此调用Id，便于应用层区别每次调用；若调用时为0，内部产生一个序号。
	* @param[in] roomInfo 房间信息。
	*
	* @note 安排房间为异步操作，调用此接口后等待回调中函数onScheduleRoomResult回调，判断是否安排成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_scheduleRoom(uint32& callId, const AVDRoomInfo& roomInfo);
	/** 根据房间Id获取房间信息
	*
	* @param[in,out] callId 调用Id，用于区别多次调用，在回调中会带上此调用Id，便于应用层区别每次调用；若调用时为0，内部产生一个序号。
	* @param[in] roomId 房间Id。
	*
	* @note 获取房间信息为异步操作，调用此接口后等待回调中函数onGetRoomResult回调，判断是否获取成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_getRoomByRoomId(uint32& callId, const char* roomId);
	/** 根据应用层房间Id获取房间信息
	*
	* @param[in,out] callId 调用Id，用于区别多次调用，在回调中会带上此调用Id，便于应用层区别每次调用；若调用时为0，内部产生一个序号。
	* @param[in] *appRoomId 应用层房间Id。
	*
	* @note 获取房间信息为异步操作，调用此接口后等待回调中函数onGetRoomResult回调，判断是否获取成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_getRoomByAppRoomId(uint32& callId, const char* appRoomId);
	/** 根据房间Id获取房间信息
	*
	* @param[in,out] callId 调用Id，用于区别多次调用，在回调中会带上此调用Id，便于应用层区别每次调用；若调用时为0，内部产生一个序号。
	* @param[in] *roomId 房间Id。
	*
	* @note 获取房间信息为异步操作，调用此接口后等待回调中函数onGetRoomResult回调，判断是否获取成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_cancelRoom(uint32& callId, const char* roomId);
	/** 根据房间号获取房间人数
	*
	* @param[in,out] callId 调用Id，用于区别多次调用，在回调中会带上此调用Id，便于应用层区别每次调用；若调用时为0，内部产生一个序号。
	* @param[in] roomId 房间Id。
	*
	* @note 获取房间人数为异步操作，调用此接口后等待回调中函数onGetUsersCountResult回调，判断是否取消成功。
	* @return 返回错误代码。
	*/
	RT_API_EXPORT Result avd_engine_getUsersCount(uint32& callId, const char* roomId);
}

#endif//RT_AVDEngine_C_H_
