//
//  NVKit.h
//  NeuVisionKit
//
//  Created by 徐家骏 on 2019/4/23.
//  Renamed by dengminhao on 2021/2/22
//
#pragma once

#ifdef SDK_SIMPLE_INCLUDE
#include "YCKitExport.h"
#include "YCKCallManagerProtocol.h"
#include "YCKLoginManagerProtocol.h"
#include "YCKDeviceManager.h"
#include "YCKUIApplication.h"
#include "YCKAudioDeviceVolumeDelegate.h"
#include "YCKTestSpeakerDelegate.h"
#else
#include <YCKit/YCKitExport.h>
#include <YCKit/Call/YCKCallManagerProtocol.h>
#include <YCKSdwan/Login/YCKLoginManagerProtocol.h>
#include <YCKit/DeviceUtil/YCKDeviceManager.h>
#include <YCKSdwan/UIProxy/YCKUIApplication.h>
#endif
#include <memory>
#include <string>
#include <vector>
#include "YCKDeviceID.h"
#include "YCKExternalAudioFilter.h"

class NeuLiveRoomMgr;

typedef std::shared_ptr<YCKCallManagerProtocol> (*CallManagerProvider)();

// 上传日志回调, 0成功, 非0失败
typedef std::function<void(int)> UploadLogCompletion;
typedef std::function<void()>    TruncatedLogCompletion;

class YCKSdwan;
class SystemMonitor;

/**
 * SDK 入口。因为Windows接口暴露的关系，这里接口本身不直接返回shared_ptr，但是使用时还是建议用shared_ptr。示例：
 * std::shared_ptr<NVKit> inst(new NVKit());
 */
class DLL_DECL NVKit
{
public:
NVKit();
NVKit(CallManagerProvider provider);

/**
 * 注意：只有registerWithOption后才能获得LoginManager
 */
virtual std::shared_ptr<YCKLoginManager> getLoginManager() const;
virtual std::shared_ptr<YCKCallManagerProtocol>  getCallManager() const;
virtual std::shared_ptr<YCKDeviceManager> getDeviceManager() const;
virtual std::shared_ptr<NeuLiveRoomMgr> getLivePushMgr();
virtual void setUIApplication(std::shared_ptr<YCKUIApplication> app);
virtual std::shared_ptr<YCKUIApplication> getUIApplication() const;
virtual void setLoginDebug(bool isDebug);

virtual std::string sdkVersion() const;

virtual std::string appID() const;

virtual void registerWithOption(std::string appId,std::string appKey,std::string srv_env="prod", std::string appDataPathPre="");
virtual void loginDirect(int64_t rid, std::string accountId, YCKLoginHandler completion);

virtual BOOL isUsingDemoAppID() const;
virtual bool flushLog();

//Not well implement yet. Will be removed later.
virtual std::string recentLogs() const; 
virtual bool clearLogs();
virtual bool enableConsoleLog();
/////////////////////////////////


virtual void disableAudio();

// = 屏幕共享
WeakYCKExternalAudioFilterPtr getExternalAudioFilter();
void setExternalAudioFilter(WeakYCKExternalAudioFilterPtr filter);
void setScreenShareOpened(bool open, uint64_t myid);

enum AudioDeviceType {
	Audio_FFmpeg_Device = 0, 
	Audio_WebRTC_Device		 
};
// 设置音频驱动类型，默认ffmpeg
void setAudioDeviceType(AudioDeviceType type);

// 设置通信是否开启加密传输
void setTransmitEncrypt(bool enable);

void setLogTruncatedCallback(TruncatedLogCompletion cb);	//= callback should not block!!

// 提交日志
virtual void uploadLog(const std::string& filePath, UploadLogCompletion completion, int64_t uid = -1, int contimeout = 8000,int rwtimeout = 15000, bool hasCrash = false);
virtual void onResumeApplication();

virtual void setLogStdoutLevel(int level);//registerWithOption 之前使用，之后无效

virtual ~NVKit();

NVKit(const NVKit &) = delete;
NVKit &operator=(const NVKit &) = delete;

protected:
    void * self;
    std::shared_ptr<YCKCallManagerProtocol> callManager;
    std::shared_ptr<NeuLiveRoomMgr> liveManager;
    std::shared_ptr<YCKDeviceManager> devicemanager;
    std::shared_ptr<SystemMonitor> systemMonitor;
//construct NVKit by given sdwan. The ownership of sdwan will be taken by the new NVKit
NVKit(std::shared_ptr<YCKSdwan>& sdwan);
};
