/***************************************************************************
 *
 * Copyright (c) 2019 Baidu.com, Inc. All Rights Reserved
 *
 * @author: sunjian
 *
 ***************************************************************************/

#pragma once
#include "BaiduExternalVideoCapturerInterface.h"
#include "BaiduExternalVideoRendererInterface.h"
#include "BaiduRtcCommonDefine.h"
#include <string>
#include <unordered_map>

namespace baidurtc {
	class BAIDU_RTC_EXPORT_API BaiduRtcRoomClient {
	public:
		/*
		 * 登录房间
		 *
		 * @param roomName 房间名，长度不超过255字节
		 * @param userId 用户id, 每个房间的用户id必须唯一
		 * @return true 成功， false 失败
		 *
		 * @discuss 登录房间成功后，用户可以发布流，或订阅流，并能通过IRtcMessageListener接口获取房间状态信息。
		 *
		 **/
		virtual bool loginRoom(char* roomId, char* userId) = 0;




		/*
		 * 登出房间
		 *
		 * @return true 成功， false 失败
		 * @discuss  关闭媒体通道，关闭信令通道，释放内存资源，及销毁其他申请的资源
		 *
		 **/
		virtual bool logoutRoom() = 0;




		/*
		 * 发布流
		 *
		 * @param isSubscribe, 标识在发布流的同时，是否订阅流，默认是订阅流的；
		 *
		 * @discuss 流发布在roomId指定的房间，在同一房间joined 的用户可以相互订阅流，默认在发布流的同时，
		 *         listening/subscriber 在该房间其他用户的流；
		 *
		 **/
		virtual void publishStreaming(bool isSubsrcibe) = 0;



		/*
		 * 发布流
		 *
		 * @param streamingIds, 指定要订阅的流Id(用户指定的房间中需要订阅的用户ID,可以指定多人)；
		 * @param steamingNum, 欲订阅的流数目;
		 *
		 * @discuss 流发布在roomId指定的房间，在同一房间joined 的用户可以相互订阅流，默认在发布流的同时，
		 *         listening/subscriber 在该房间其他用户的流；该API可以指定要订阅的具体多条流或多个用户的流。
		 *
		 **/
		virtual void publishStreaming(char* streamingIds[],int streamingNum) = 0;



		/*
		 * 订阅流
		 *
		 * @param streamingIds[], 用户要订阅的其他用户的流id列表(即其他用户id列表)
		 * @param streamingNum, 欲订阅的流数目，即streamingIds[]的大小
		 *
		 * @discuss 用于订阅同一房间的其他用户的流
		 *
		 **/
		virtual void subscribeStreaming(char* streamingIds[], int streamingNum) = 0;




		/*
		 * 停止发布流
		 *
		 * @discuss  publishing的流都可通过该interface停止发布或订阅
		 *
		 **/
		virtual void stopPublishStreaming() = 0;




		/*
		 * 停止订阅流
		 *
		 * @param streamingIds[], 用户要停止订阅的流id列表(即其他用户id列表)
		 * @param streamingNum, 欲停止订阅的流数目，即streamingIds[]的大小
		 *
		 * @discuss  publishing and subscribering 的流都可通过该interface停止发布或订阅
		 *
		 **/
		virtual void stopSubscribeStreaming(char* streamingIds[], int streamingNum) = 0;



		/*
		 * 注册视频数据帧到达Observer
		 *
		 *
		 * @param iVfo[], 数据帧到达Observer接口数组，多个接口可多路流，一个接口listening一路流；
		 * @param iVfoNum, Observer 接口数
		 *
		 * @discuss 当使用外部渲染时，需要注册视频数据监测接口，有视频数据到来时，可通知用户去做渲染或其他处理。
		 *          接口详细信息可查看头文件：BaiduExternalVideoRendererInterface.h
		 *
		 **/
		virtual void registerVideoFrameObserver(IVideoFrameObserver* iVfo[], int iVfoNum) = 0;




		/*
		 * 注册外部视频采集设备
		 *
		 *
		 * @param videoCd, 视频采集设备接口
		 *
		 * @discuss 当用户需要自己控制采集设备时，可实现参数定义的接口，并通过该接口注册到SDK, SDK 接通过该接口
		            获取外部采集的视频数据.接口详细信息可查看头文件：BaiduExternalVideoCapturerInterface.h
		 *
		 *
		 **/
		virtual void registerExternalVideoCapturer(std::shared_ptr<IVideoCapturerDevice> videoCd) = 0;




		/*
		 * 注册消息监听接口
		 *
		 *
		 * @param msgListener, rtc sdk 消息上报接口
		 *
		 * @discuss 用户可以实现参数定义的接口，并通过该接口注册，当sdk 启动后，可以收到来自sdk的消息，并做相应的处理。
		 *          接口详细信息可查看头文件：BaiduRtcCommonDefine.h
		 *
		 **/
		virtual void registerRtcMessageListener(IRtcMessageListener* msgListener) = 0;




		/*
		 * 设置视频编码码率
		 *
		 * @param bitRate, 需要设置视频码率值，如设置300kbps, 则bitRate = 300*1024;
		 *
		 * @discuss 该接口用于设置视频编码码率，sdk 会根据网络状况做自适应码率调整，但不会超过通过该接口设置的码率
		 *          即以该值为最大码率；
		 *
		 **/
		virtual void setBitRate(int bitRate) = 0;




		/*
		 * 设置视频采集分辨率
		 *
		 * @param width, 视频采集宽；
		 * @param height, 视频采集高；
		 *
		 * @discuss  用于设置视频采集分辨率，若使用外部视频采集，就无需设置；
		 *
		 **/
		virtual void setResolution(int width, int height) = 0;




		/*
		 * 设置视频采集帧率
		 *
		 * @param fps, 视频采集的帧率，如15fps, 24fps, 29fps等
		 *
		 **/
		virtual void setFps(int fps) = 0;



		/*
		 * 设置视频颜色空间格式
		 *
		 * @param fps, 支持的视频颜色空间格式ARGB/I420
		 *
		 **/
		virtual void setVideoFromat(VideoColorFormat vcf) = 0;



		/*
		 * 设置镜像
		 *
		 * @param isOpenMirror, 设置是否打开镜像功能
		 *
		 **/
		virtual void setVideoMirror(bool isOpenMirror) = 0;



		/*
		 * 打开摄像头
		 *
		 * @param deviceName, 设备名称，若为空，开启默认的设备，否则开启指定的设备
		 * @discuss  打开摄像头后，可开始画面预览
		 *
		 **/
		virtual void openCamera(char* deviceName) = 0;



		/*
		 * 关闭摄像头
		 *
		 * @discuss  关闭并释放摄像头资源
		 *
		 **/
		virtual void closeCamera() = 0;



		/*
		 * Mute摄像头
		 *
		 * @discuss  关闭摄像头，停止画面预览及传输
		 *
		 **/
		virtual void muteCamera(bool isMuted) = 0;



		/*
		 * Mute麦克风
		 *
		 * @discuss  关闭麦克风，停止音频采集及传输
		 *
		 **/
		virtual void muteMicphone(bool isMuted) = 0;



		/*
		 * 音量控制
		 *
		 * @param volume, 音量值，范围 0 ~ 10
		 * @discuss  用于控制扬声器音量的大小
		 *
		 **/
		virtual void setVolume(uint32_t volume) = 0;



		/*
		 * 开始预览
		 *
		 * @discuss  打开摄像头后，可开始画面预览
		 *
		 **/
		virtual void startPreview() = 0;




		/*
		 * 停止预览
		 *
		 * @discuss  在开始预览后，可通过该接口停止预览
		 *
		 **/
		virtual void stopPreview() = 0;



		/*
		 * 屏幕共享
		 *
		 * @discuss 可通过该接口开启屏幕分享功能, 让其他用户看到你的屏幕操作
		 *
		 **/
		virtual void startShareScreen() = 0;



        /*
        * 屏幕共享
        *
        * @param sourceId 屏幕ID,通过getWindowSourceList获取;
        *
        * @discuss 可通过该接口开启屏幕分享功能, 让其他用户看到你的屏幕操作;通过sourceId指定分享的屏幕;
         *
         **/
        virtual void startShareScreenWithSource(long long sourceId) = 0;



        /*
        * 获取可共享屏幕/窗口列表
        *
        * @param type 共享类型;
        * @param count 返回获取列表长度
        *
        * @discuss 可通过该接口获取可共享屏幕/窗口列表
        *
        **/
        virtual WindowSource* getWindowSourceList(CaptureType type, int& count) = 0;



        /*
         * 释放共享屏幕/窗口列表
         *
         * @discuss 释放共享屏幕/窗口列表
         *
         **/
        virtual void freeWindowSourceList(WindowSource* sourceList, int length) = 0;



		/*
		 * 停止屏幕共享
		 *
		 * @discuss 关闭屏幕分享功能
		 *
		 **/
	    virtual void stopShareScreen() = 0;



        /*
         * 窗口共享
         *
         * @param sourceId 窗口Wid,通过getWindowSourceList获取,或者外部获取传入;
         *
         * @discuss 可通过该接口开启窗口分享功能, 让其他用户看到你的窗口操作;通过sourceId指定分享的窗口;
         *
         **/
        virtual void startShareWindow(long long sourceId) = 0;



        /*
         * 停止窗口共享
         *
         *
         * @discuss 关闭窗口分享功能
         *
         **/
        virtual void stopShareWindow() = 0;



		/*
		 * 发送消息
		 *
		 * @param message, 准备发的消息
		 * @discuss 可通过该接口发送文本消息到聊天室，房间的其他人能接收到所发消息
		 *
		 **/
		virtual void sendMessage(const char* message) = 0;



		/*
		 * 查询房间信息
		 *
		 * @param message, 准备发的消息
		 * @discuss 可通过该接口发送文本消息到聊天室，房间的其他人能接收到所发消息
		 *
		 **/
		virtual void getRoomStates(RtcRoomUserInfo** userInfoList, int& userNumber) = 0;




		/*
		 * 获取当前网络状态
		 *
		 * @param ConnectionType,网络连接类型，信令通道连接/媒体通道连接
		 * @return ConnectionStats, 网络连接状态值
		 * @discuss 根据连接类型，返回用户当前的网络连接状态值
		 *
		 **/
		virtual ConnectionStats getConnectionStats(ConnectionType connectionType) = 0;




		/*
		 * RTC状态信息打点
		 *
		 * @discuss 是否开启RTC状态信息打点功能，默认开启。当开启打点时，日志信息会上传到百度
		 *  日志统计server,并通过图表的形式展示，可实时查询。
		 *
		 **/
		virtual void enableRtcStatsInfoDot(bool isEnable) = 0;



        /*
         * 配置server端推流参数
         *
         * @param rtc_client rtc client 句柄;
         * @param url rtmp推流地址;
         * @param is_mix 是否做混流处理;
         * @param is_recording 是否录制;
         * @param mix_template 混流模板;
         * @param transfer_mode 转推模式，有两种： 聊天室模式， 主播转推模式;
         *
         * @discuss 该接口用于配置server推流的参数，聊天室模式：在同一个rtc房间的所有参与者在混流后，直接转推到一个指定的直播房间；
         *    主播转推模式：主播推向不同的直播房间;进入房间前调用;
         *
         **/
        virtual bool configLiveStreamWithUrl(char* url, bool isMix,
            bool isRecording, char* mixTemplate, RtcLiveTransferMode transferMode) = 0;



        /*
         * 启动动态转推功能
         *
         * @param rtc_client rtc client 句柄;
         * @param url rtmp推流地址;
         * @param is_mix 是否做混流处理;
         * @param is_recording 是否录制;
         * @param mix_template 混流模板;
         * @param transfer_mode 转推模式，有两种： 聊天室模式， 主播转推模式;
         *
         * @discuss 启动动态转推功能,进入房间成功后调用;
         *
         **/
        virtual bool startLiveServerStreaming(char* url, bool isMix,
            bool isRecording, char* mixTemplate, RtcLiveTransferMode transferMode) = 0;



        /*
         * 停止动态转推功能
         *
         * @param rtc_client rtc client 句柄;
         *
         * @discuss 停止动态转推功能
         *
         **/
        virtual bool stopLiveServerStreaming(RtcLiveTransferMode transferMode) = 0;
	};

	class BAIDU_RTC_EXPORT_API BaiduRtcConfigure {
	public:
		/*
		 * 配置Rtc SDK 环境
		 *
		 * @discuss 配置sdk环境，须在initializeBaiduRtcSdk接口之前调用
		 *
		 **/
		virtual void configureRtcSdk() = 0;



		/*
		 * 释放Rtc SDK 环境配置资源
		 *
		 * @discuss 释放configureRtcSdk接口配置的资源，在deInitializeBaiduRtcSdk接口之后调用，
		 *          清楚sdk 占用的所有资源
		 *
		 **/
		virtual void deConfigureRtcSdk() = 0;
	};

	/*
	 * 创建RtcSdk配置
	 *
	 * @discuss  返回 BaiduRtcConfigure, 用于sdk环境配置
	 *
	 **/
	BAIDU_RTC_EXPORT_API std::unique_ptr<BaiduRtcConfigure> createBaiduRtcConfigure();




	/*
	 * 初始化SDK
	 *
	 * @param appId, 百度提供给开发者的数字签名，是开发者的唯一标识
	 * @param token, 用于信令交互时，与server端鉴权
	 * @param cerPath, ssl 证书存放路径，证书有百度提供
	 * @discuss 该interface用于初始化windows rtc sdk, 需在使用之前调用进行初始化
	 *
	 **/
	BAIDU_RTC_EXPORT_API void initializeBaiduRtcSdk(char* appId, char* token, char* cerPath);




	/*
	 * 释放SDK
	 *
	 * @discuss 在sdk使用完后，可调用该sdk进行释放，销毁操作
	 *
	**/
	BAIDU_RTC_EXPORT_API void deInitializeBaiduRtcSdk();




	/*
	 * 创建BaiduRtcRoomClient
	 * 
	 * @discuss  用户使用该sdk开发的入口，首先需要创建BaiduRtcRoomClient, 通过该client 初始化sdk，发布流，订阅流等其他
	 *           可提供的api操作
	 */
	BAIDU_RTC_EXPORT_API std::unique_ptr<BaiduRtcRoomClient> createBaiduRtcRoomClient();



	/*
	 * 获取SDK版本号
	 *
	 * @return  返回版本号字符串
	 *
	 * @discuss 获取百度RTC SDK 版本号
	 *
	 **/
	BAIDU_RTC_EXPORT_API void getBaiduRtcSdkVersion(char* version, int len);



	/*
	 * 日志功能
	 *
	 * @param, isEnable, 若为true, 开启日志功能， 开启日志功能后，会把日志保存到本地文件中；
	 *                   若为false 关闭日志功能。
	 *
	 * @discuss SDK 日志功能开关, 谨记在卸载SDK时需disable。
	 *
	 **/
	BAIDU_RTC_EXPORT_API void enableBaiduRtcLog(bool isEnable);



	/*
	 * 切换媒接入SERVER
	 *
	 * @discuss 当链路不稳定，或视频画面卡顿时，可使用该接口，切换媒体接入server. 切换后，需要重新进入房间，并发布流或拉流。
	 *
	 **/
	BAIDU_RTC_EXPORT_API void configStreamingAddr(const char* url);




	/*
	 * 获取视频设备列表
	 *
	 * @param deviceCount, 可用设备数目
	 * @return RtcVideoDeviceInfo*, 指向当前可用信息列表
	 * @discuss 获取当前可用的视频设备列表，用户可根据获取的列表，选择要开启的视频设备
	 *
	 **/
	BAIDU_RTC_EXPORT_API RtcVideoDeviceInfo* getVideoDeviceList(int & deviceCount);



	/*
	 * 释放视频设备列表
	 *
	 * @discuss 当用户调用getVideoDeviceList获取视频设备列表后，须使用该接口是否释放设备列表资源
	 *
	 **/
	BAIDU_RTC_EXPORT_API void freeVideoDeviceList(RtcVideoDeviceInfo* deviceInfoList);



	/*
	 * 设置视频设备
	 *
	 * @param deviceId, 视频设备id 或 name
	 * @discuss 用户通过getVideoDeviceList 获取的设备信息列表，设置准备开启的视频设备
	 *
	 **/
	BAIDU_RTC_EXPORT_API void setVideoDevice(const char* deviceId);

}//namespace baidurtc

