// Fill out your copyright notice in the Description page of Project Settings.


#include "Manager/CsdkVoiceSupportSubsystem.h"
#include "Log/CsdkLogMacros.h"
#include "Log/LogChatSdk.h"
#include "Tools/CsdkCommonTools.h"
#include "Voice/CsdkVoiceBase.h"
#include "Voice/Data/CsdkMicState.h"
#include "Voice/Data/CsdkSpeakerState.h"


void UCsdkVoiceSupportSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);
#if UE_SERVER	
	return;
#endif
}

void UCsdkVoiceSupportSubsystem::Deinitialize()
{
	Super::Deinitialize();
#if UE_SERVER	
	return;
#endif
}

bool UCsdkVoiceSupportSubsystem::Init(UCsdkVoiceBase* VoiceObj)
{
#if UE_SERVER	
	return {};
#endif
	Voice = VoiceObj;
	if(Voice)
	{
		bIsInit =Voice->Init(this);

#if PLATFORM_ANDROID
		AndroidGateway = MakeShareable(new FAndroidGateway);
#endif
		
		return bIsInit;
	}
	CSDK_LOG(LogChatSdk,Error,TEXT("Init Failed!, UCsdkVoiceBase is null"))
	return false;
}

int32 UCsdkVoiceSupportSubsystem::Uninit()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't Uninit before Init Success"));
#endif
	if(Voice)
		return Voice->UnInit();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("Uninit Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::Pause()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't Pause before Init Success"));
#endif
	
	if(Voice)
		return Voice->Pause();

	CSDK_LOG(LogChatSdk,Error,TEXT("Pause Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::Resume()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't Resume before Init Success"));
#endif
	if(Voice)
		return Voice->Resume();

	CSDK_LOG(LogChatSdk,Error,TEXT("Resume Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::StartRecording(const FRecordFileCompleted& OnRecordFileCompleted)
{
#if UE_SERVER	
	return {};
#endif
#if PLATFORM_ANDROID
	if (!AndroidGateway->IsPermissionRecordAudioGranted())
	{
		AndroidGateway->AskPermissionRecordAudio();
		return -1;
	}

#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit, TEXT("Can't StartRecording before Init Success"));
#endif	
	
	if (Voice)
		return Voice->StartRecording(OnRecordFileCompleted);

	CSDK_LOG(LogChatSdk, Error, TEXT("StartRecording Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::StopRecording() 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't StopRecording before Init Success"));
#endif	
	
	if(Voice)
		return Voice->StopRecording();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("StopRecording Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::CancelRecording() 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't CancelRecording before Init Success"));
#endif	
	
	if(Voice)
		return Voice->CancelRecording();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("CancelRecording Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::UploadRecordedFile(const FString& FilePath, const FUploadRecordedFileCompleted& OnUploadRecordedFileCompleted) 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't UploadRecordedFile before Init Success"));
#endif	
	if(Voice)
		return Voice->UploadRecordedFile(FilePath, OnUploadRecordedFileCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("CancelRecording Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::DownloadRecordedFile(
	const FString& FileId, const FDownloadRecordedFileCompleted& OnDownloadRecordedFileCompleted) 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't DownloadRecordedFile before Init Success"));
#endif	
	if(Voice)
		return Voice->DownloadRecordedFile(FileId,OnDownloadRecordedFileCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("CancelRecording Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::PlayRecordedFile(const FString& FilePath,
	const FPlayRecordedFileCompleted& PlayRecordedFileCompleted) 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't PlayRecordedFile before Init Success"));
#endif	
	if(Voice)
		return Voice->PlayRecordedFile(FilePath,PlayRecordedFileCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("PlayRecordedFile Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::StopPlayFile() 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't StopPlayFile before Init Success"));
#endif
	if(Voice)
	{
		CsdkOnStopPlayVoice.Broadcast();
		return Voice->StopPlayFile();
	}
		
	
	CSDK_LOG(LogChatSdk,Error,TEXT("StopPlayFile Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::GetFileSize(const FString& FilePath) const
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetFileSize before Init Success"));
#endif
	if(Voice)
		return Voice->GetFileSize(FilePath);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("GetFileSize Failed!, UCsdkVoiceBase is null"))
	return -1;
}

float UCsdkVoiceSupportSubsystem::GetVoiceFileDuration(const FString& FilePath) const{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetVoiceFileDuration before Init Success"));
#endif
	if(Voice)
		return Voice->GetVoiceFileDuration(FilePath);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("GetVoiceFileDuration Failed!, UCsdkVoiceBase is null"))
	return -1.0f;
}

int32 UCsdkVoiceSupportSubsystem::SpeechToText(const FString& FileId,const FSpeechToTextCompleted& SpeechToTextCompleted) 
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't SpeechToText before Init Success"));
#endif
	if(Voice)
		return Voice->SpeechToText(FileId,SpeechToTextCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("SpeechToText Failed!, UCsdkVoiceBase is null"))
	return -1.0f;
}

int32 UCsdkVoiceSupportSubsystem::StartStreamSpeechToText(const FStreamSpeechToTextRunning& StreamSpeechToTextRunning,
		const FStreamSpeechToTextCompleted& StreamSpeechToTextCompleted)
{
#if UE_SERVER	
	return {};
#endif
#if PLATFORM_ANDROID
	if (!AndroidGateway->IsPermissionRecordAudioGranted())
	{
		AndroidGateway->AskPermissionRecordAudio();
		return -1;
	}
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't StartStreamSpeechToText before Init Success"));
#endif
	if(Voice)
		return Voice->StartStreamSpeechToText(StreamSpeechToTextRunning,StreamSpeechToTextCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("StartStreamSpeechToText Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::StopStreamSpeechToText()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't StopStreamSpeechToText before Init Success"));
#endif
	if(Voice)
		return Voice->StopStreamSpeechToText();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("StopStreamSpeechToText Failed!, UCsdkVoiceBase is null"))
	return -1;
}


int32 UCsdkVoiceSupportSubsystem::EnterVoiceRoom(const FString& RoomId,const FEnterRoomCompleted& EnterRoomCompleted)
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't EnterVoiceRoom before Init Success"));
#endif
	if(Voice)
		return Voice->EnterVoiceRoom(RoomId,EnterRoomCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("EnterChatRoom Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::ExitVoiceRoom(const FExitRoomCompleted& ExitRoomCompleted)
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't ExitVoiceRoom before Init Success"));
#endif
	if(Voice)
		return Voice->ExitVoiceRoom(ExitRoomCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("ExitChatRoom Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::SwitchVoiceRoom(const FString& RoomId, const FSwitchRoomCompleted& SwitchRoomCompleted)
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't SwitchVoiceRoom before Init Success"));
#endif
	if(Voice)
		return Voice->SWitchVoiceRoom(RoomId, SwitchRoomCompleted);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("SwitchVoiceRoom Failed!, UCsdkVoiceBase is null"))
	return -1;
}

TArray<FString> UCsdkVoiceSupportSubsystem::GetVoiceRoomMemberOpenIds() const
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetVoiceRoomMemberOpenIds before Init Success"));
#endif
	if(Voice)
		return Voice->GetVoiceRoomMemberOpenIds();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("ExitChatRoom Failed!, UCsdkVoiceBase is null"))
	return TArray<FString>{};
}


int32 UCsdkVoiceSupportSubsystem::OpenMic()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't OpenMic before Init Success"));
#endif
	if(Voice)
		return Voice->OpenMic();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("OpenMic Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::CloseMic()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't CloseMic before Init Success"));
#endif
	if(Voice)
		return Voice->CloseMic();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("CloseMic Failed!, UCsdkVoiceBase is null"))
	return -1;
}

ECsdkMicState UCsdkVoiceSupportSubsystem::GetMicState()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetMicState before Init Success"));
#endif
	if(Voice)
		return Voice->GetMicState();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("GetMicState Failed!, UCsdkVoiceBase is null"))
	return ECsdkMicState::Closed;
}

int32 UCsdkVoiceSupportSubsystem::OpenSpeaker()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't OpenSpeaker before Init Success"));
#endif
	if(Voice)
		return Voice->OpenSpeaker();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("OpenSpeaker Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::CloseSpeaker()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't CloseSpeaker before Init Success"));
#endif
	if(Voice)
		return Voice->CloseSpeaker();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("CloseSpeaker Failed!, UCsdkVoiceBase is null"))
	return -1;
}

ECsdkSpeakerState UCsdkVoiceSupportSubsystem::GetSpeakerState()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetSpeakerState before Init Success"));
#endif
	if(Voice)
		return Voice->GetSpeakerState();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("GetSpeakerState Failed!, UCsdkVoiceBase is null"))
	return ECsdkSpeakerState::Closed;
}

bool UCsdkVoiceSupportSubsystem::HasVoiceRoom()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't HasVoiceRoom before Init Success"));
#endif
	if(Voice)
		return Voice->HasVoiceRoom();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("HasVoiceRoom Failed!, UCsdkVoiceBase is null"))
	return false;
}

void UCsdkVoiceSupportSubsystem::ModifyUserMicStatus(FString VoiceRoomId, TArray<FCsdkUserMicStatus> UserStatus,
                                                     FModifyUserMicStatusCallback Callback)
{
	FCsdkCommonTools::GetVoiceManager().ModifyUserMicStatus(VoiceRoomId, UserStatus, Callback);
}

int32 UCsdkVoiceSupportSubsystem::SetMicVolume(int32 Vol)
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't SetMicVolume before Init Success"));
#endif
	if(Voice)
		return Voice->SetMicVolume(Vol);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("SetMicVolume Failed!, UCsdkVoiceBase is null"))
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::GetMicVolume()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetMicVolume before Init Success"));
#endif
	if(Voice)
		return Voice->GetMicVolume();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("GetMicVolume Failed!, UCsdkVoiceBase is null"));
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::SetSpeakerVolume(int32 Vol)
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't SetSpeakerVolume before Init Success"));
#endif
	if(Voice)
		return Voice->SetSpeakerVolume(Vol);
	
	CSDK_LOG(LogChatSdk,Error,TEXT("SetSpeakerVolume Failed!, UCsdkVoiceBase is null"));
	return -1;
}

int32 UCsdkVoiceSupportSubsystem::GetSpeakerVolume()
{
#if UE_SERVER	
	return {};
#endif
#if CSDK_WITH_CHECK
	checkf(bIsInit,TEXT("Can't GetSpeakerVolume before Init Success"));
#endif
	if(Voice)
		return Voice->GetSpeakerVolume();
	
	CSDK_LOG(LogChatSdk,Error,TEXT("GetSpeakerVolume Failed!, UCsdkVoiceBase is null"));
	return -1;
}
