//
//  TrroRemote.h
//  TrroIOS
//
//  Created by Robin on 2023/5/22.
//

#import <Foundation/Foundation.h>
#import <TRROControl/TrroRemoteDef.h>
#import <TRROControl/TrroRemoteDelegate.h>
#import <TRROControl/TrroGateway.h>
#import <TRROControl/TrroConnectParam.h>
#import <TRROControl/TrroRenderConfig.h>
#import <TRROControl/TrroOptions.h>
#import <TRROControl/TrroExperimentOptions.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, AudioOutputType) {
    AudioOutputTypeSpeaker,    // 扬声器
    AudioOutputTypeReceiver,   // 听筒
    AudioOutputTypeAutomatic   // 自动
};

@interface TrroRemote : NSObject

/// 创建 TrroRemote 实例（单例模式）
+ (instancetype)sharedInstance;

/// 销毁 TrroRemote 实例（单例模式）
+ (void)destroySharedInstance;

/// 设置 事件回调代理 及 回调队列
/// @param delegate 事件回调代理
/// @param delegateQueue TrroControlDelegate 事件回调的队列
- (void)setDelegate:(id<TrroRemoteDelegate>)delegate delegateQueue:(dispatch_queue_t)delegateQueue;

/**
 * 使用options配置方式初始化控制端，接口为同步阻塞模式.
 *
 * @param trroOptions 配置选项
 * @return 成功 1 失败 <= 0
 */
- (int)setupWithOptions:(TrroOptions *)trroOptions;

/**
 * 使用json字符串初始化控制端，字段格式参考：https://cloud.tencent.com/document/product/1584/89794
 *
 * @param jsonStr json配置信息，接口为同步阻塞模式.
 * @return 成功 1 失败 <= 0
 */
- (int)setupWithJson:(NSString *)jsonStr;

/**
 * 获取网关列表，接口为同步阻塞模式.
 *
 * @return 网关列表
 */
- (TrroGatewayList*)getGwList;

/**
 * 获取对应网关的详细信息，接口为同步阻塞模式.
 *
 * @param gwid 设备id 公有云含projectID前缀
 * @return 网关信息对象
 */
- (TrroGateway *)getGwInfoForGwid:(NSString *)gwid;

/**
 * 连接1路视频流
 *
 * @param gwid 网关ID
 * @param connectParam 视频流配置参数
 * @return 成功 1 失败 <= 0
 */
- (int)connectToGwid:(NSString *)gwid connectParam:(TrroConnectParam *)connectParam;

/**
 * 连接多路视频流
 *
 * @param gwid 网关ID
 * @param connectParamList 视频流配置参数
 * @return 成功 1 失败 <= 0
 */
- (int)connectToGwid:(NSString *)gwid connectParamList:(NSArray<TrroConnectParam *> *)connectParamList;

/**
 * 关闭连接
 *
 * @param connFds 连接句柄
 * @return 成功 1 失败 <= 0
 */
- (int)disconnect:(NSArray<NSNumber *> *)connFds;

/**
 * 关闭所有连接
 *
 * @return 成功 1 失败 <= 0
 */
- (int)disconnectAll;

/**
 * 发送控制消息
 *
 * @param msg 消息内容
 * @param qos 是否可靠发送， 0:unreliable  1:reliable
 * @param gwid 网关ID
 * @return 成功 1 失败 <= 0
 */
- (int)sendControlMsg:(NSData *)msg qos:(int)qos toGwid:(NSString *)gwid;


/**
 * 向现场设备发送控制数据
 *
 * @param msg     发送消息，二进制透传
 * @param qos    是否可靠发生，0:unreliable 1:reliable
 * @param gwid  目标现场设备id
 * @param channel     通道号，默认0 (目前仅支持0)
 * @param expiredMs   QoS1（qos=1，可靠传输）下允许重传的最大时间（毫秒）：
 *                  <=0（默认）：走原有完全可靠传输（reliable=true），行为保持不变。
 *                  >0 ：QoS1 场景下希望降低丢包率、 但可以容忍时限内放弃的业务。
 *                  qos=0（QoS0，不可靠传输）时，本参数被忽略，保持原有 fire-and-forget 立即过期行为。
 * @return 成功 1 失败 <= 0
*/
- (int)sendControlMsgV2:(NSData *)msg qos:(int)qos gwid:(NSString *)gwid channel:(int)channel expiredMs:(int)expiredMs;

/**
 * 外部音频数据输入(pcm数据), 16位音频采样
 *
 * @param data 音频pcm数据
 * @param channel 音频声道数
 * @param sampleRate 音频采样率
 * @param gwid 网关Id
 * @param completion code为1成功， <= 0 失败
 */
- (void)externalAudioData:(NSData *)data
                  channel:(int)channel
               sampleRate:(int)sampleRate
                  forGwid:(NSString *)gwid
               completion:(nullable void (^)(int code))completion;


/**
 * 外部音频数据输入(pcm数据)，带用户时间戳
 * userTime 会随音频流透传到对端，可用于业务侧端到端时延统计或与视频帧userTime 对齐。
 * 若不需要传 userTime，请使用 externalAudioData:channel:sampleRate:forGwid:completion:
 *
 * @param userTime 用户自定义时间戳（典型为 epoch ms），随音频流透传到对端
 * @param data 音频pcm数据
 * @param channel 音频声道数
 * @param sampleRate 音频采样率
 * @param gwid 网关Id
 * @param completion code为1成功， <= 0 失败
 */
- (void)externalAudioDataWithUserTime:(unsigned long long)userTime 
                                 data:(NSData *)data
                              channel:(int)channel
                           sampleRate:(int)sampleRate
                              forGwid:(NSString *)gwid
                           completion:(nullable void (^)(int code))completion;

/**
 * Mute/unMute 目标现场设备的音频 仅Server模式
 *
 * @param mute true 静音， false 取消静音
 * @param gwid 目标现场设备id
 * @return 成功 1 失败 <= 0
 */
- (int)audioMute:(BOOL)mute forGwid:(NSString *)gwid;

/**
 * 实验API，可配置切换软硬解
 *
 * @param options 实验配置参数
 */
- (void)callExperimentApi:(TrroExperimentOptions *)options;

/**
 * 向网关发出权限请求
 *
 * @param permission 参考结构体 Trro_Permission
 * @param gwid 目标设备id
 * @return 成功1 失败 <= 0
 */
- (int)requestPermission:(Trro_Permission)permission forGwid:(NSString *)gwid;

/// 获取SDK版本号
/// @return  当前版本号
- (NSString *)getVersion;

/**
 * 更新现场设备目标视频流编码参数
 *
 * @param encodeConfig 待更新的编码参数 ，json格式字符串，缺省字段将保持当前值不进行更新。
 * @param gwid 现场设备id
 * @param streamId 目标视频流编号
 */
- (int)fieldDeviceEncodeConfig:(NSString *)encodeConfig gwid:(NSString *)gwid streamId:(int)streamId;


/**
 * 白名单模式下，针对未注册设备观看，用于观看身份验证
 *
 * @param gwid 授权现场设备ID， project_id/device_id
 * @param signature 基于项目密钥签发的临时授权签名
 * @return 成功 1 失败 <= 0
 */
- (int)setSessionPermissionToken:(NSString *)signature gwid:(NSString *)gwid;

/**
 * 需要主动触发，诊断网关、控制端当前状态输出报告
 *
 * @param gwid 目标设备id
 * @return 成功 1 失败 <= 0
 */
- (int)diagRequest:(NSString *)gwid;

/**
 * 本地麦克风静音/取消静音
 *
 * @param mute 是否静音  true静音，false取消静音
 */
- (void)localAudioMute:(BOOL)mute;

/**
 * 创建截屏
 *
 * @param confd  连接句柄
 * @param filepath 文件存储路径
 * @return 截图保存文件完整文件名，失败返回nil
 */
- (NSString *)createSnapShotWithConfd:(NSNumber *)confd filePath:(NSString *)filepath;

/**
 * 开始录制视频
 *
 * @param connFd  连接句柄
 * @param filePath 视频存储路径
 * @param expectAudio 是否录制音频
 */
- (void)startRecordWithConnFd:(NSNumber *)connFd filePath:(NSString *)filePath expectAudio:(BOOL)expectAudio;

/**
 * 停止录制视频
 *
 * @param connFd  连接句柄
 * @param completion 停止录制回调，success 录制是否成功，filePath 录制文件路径
 */
- (void)stopRecordWithConnFd:(NSNumber *)connFd completion:(void (^_Nullable)(BOOL success, NSString *filePath))completion;

@end

NS_ASSUME_NONNULL_END
