#include "HyperTwistRecognition/HyperTwistVoiceClient.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

TArray<FHyperTwistVoiceProfileSummary> UHyperTwistMockVoiceClient::ListVoiceProfiles() const
{
	return UHyperTwistContractLibrary::MakeSampleVoiceProfiles();
}

FHyperTwistNarrationSynthesisResult UHyperTwistMockVoiceClient::SynthesizeNarration(
	const FHyperTwistNarrationSynthesisRequest& Request
)
{
	FHyperTwistNarrationSynthesisResult Result = UHyperTwistContractLibrary::MakeMockNarrationSynthesisResult();
	Result.RequestId = Request.RequestId;
	Result.NarrationContractId = Request.NarrationContractId;
	Result.ServiceLaneId = Request.ServiceLaneId;
	Result.OutputRouteId = Request.OutputRouteId;
	Result.VoiceProfileId = Request.VoiceProfileId;
	Result.LanguageCode = Request.LanguageCode;
	Result.OrchestrationProfileId = Request.OrchestrationProfile.OrchestrationProfileId;
	Result.ModelBindingId = Request.OrchestrationProfile.ModelBindingId;
	Result.VocoderBindingId = Request.OrchestrationProfile.VocoderBindingId;
	Result.SpeakerProfileId = Request.SpeakerProfileId.IsEmpty()
		? Request.OrchestrationProfile.DefaultSpeakerProfileId
		: Request.SpeakerProfileId;
	Result.SubtitleText = Request.SubtitleSeedText.IsEmpty() ? Request.ScriptText : Request.SubtitleSeedText;
	Result.AppliedLengthScale = Request.LengthScale;
	Result.AppliedNoiseScale = Request.NoiseScale;
	Result.AppliedNoiseW = Request.NoiseW;
	Result.AppliedSentenceSilenceSeconds = Request.SentenceSilenceSeconds;
	Result.bUsedSentenceSplitting = Request.bSplitSentences || Request.OrchestrationProfile.bEnableSentenceSplitting;
	Result.bUsedSpeakerSelection =
		Request.OrchestrationProfile.bEnableSpeakerSelection && !Result.SpeakerProfileId.IsEmpty();
	Result.bUsedSpeakerReferenceConditioning =
		Request.OrchestrationProfile.bEnableSpeakerReferenceConditioning && !Request.ReferenceVoiceSampleRef.IsEmpty();

	if (!Request.IsStructurallyValid())
	{
		Result = FHyperTwistNarrationSynthesisResult();
		Result.RequestId = Request.RequestId;
		Result.NarrationContractId = Request.NarrationContractId;
		Result.ServiceLaneId = Request.ServiceLaneId;
		Result.OutputRouteId = Request.OutputRouteId;
		Result.VoiceProfileId = Request.VoiceProfileId;
		Result.LanguageCode = Request.LanguageCode;
		Result.OrchestrationProfileId = Request.OrchestrationProfile.OrchestrationProfileId;
		Result.ModelBindingId = Request.OrchestrationProfile.ModelBindingId;
		Result.VocoderBindingId = Request.OrchestrationProfile.VocoderBindingId;
		Result.SpeakerProfileId = Request.SpeakerProfileId.IsEmpty()
			? Request.OrchestrationProfile.DefaultSpeakerProfileId
			: Request.SpeakerProfileId;
		Result.Warnings.Add(TEXT("narration-request-invalid"));
		return Result;
	}

	bool bKnownProfile = false;
	for (const FHyperTwistVoiceProfileSummary& Profile : UHyperTwistContractLibrary::MakeSampleVoiceProfiles())
	{
		if (Profile.VoiceProfileId.Equals(Request.VoiceProfileId, ESearchCase::IgnoreCase))
		{
			bKnownProfile = true;
			break;
		}
	}

	if (!bKnownProfile)
	{
		Result.Warnings.Add(TEXT("voice-profile-not-found"));
	}

	return Result;
}

FHyperTwistVoiceServiceHealth UHyperTwistMockVoiceClient::GetVoiceServiceHealth() const
{
	FHyperTwistVoiceServiceHealth Health = UHyperTwistContractLibrary::MakeMockVoiceServiceHealth();
	Health.ProviderLabel = TEXT("mock");
	Health.ServiceEndpoint = TEXT("in-process://mock");
	Health.Capabilities.AddUnique(TEXT("offlineNarration"));
	Health.Capabilities.AddUnique(TEXT("voiceCatalog"));
	Health.Capabilities.AddUnique(TEXT("wavOutput"));
	Health.Capabilities.AddUnique(TEXT("subtitleSeed"));
	Health.Capabilities.AddUnique(TEXT("multiSpeakerNarration"));
	Health.Capabilities.AddUnique(TEXT("multiLingualNarration"));
	Health.Capabilities.AddUnique(TEXT("speakerReferenceConditioning"));
	Health.Capabilities.AddUnique(TEXT("sentenceSplitNarration"));
	Health.Capabilities.AddUnique(TEXT("modelBindingSelection"));
	Health.Capabilities.AddUnique(TEXT("vocoderBindingSelection"));
	Health.Capabilities.AddUnique(TEXT("downloadableVoiceAssetReview"));
	Health.Capabilities.AddUnique(TEXT("voiceModelCardReview"));
	Health.Capabilities.AddUnique(TEXT("downloadableVoiceModelReview"));
	Health.Capabilities.AddUnique(TEXT("modelLicenseSelectionReview"));
	Health.Capabilities.AddUnique(TEXT("termsAcceptanceReview"));
	Health.SupportedOrchestrationProfiles.AddUnique(TEXT("local-basic-narration-v1"));
	Health.SupportedOrchestrationProfiles.AddUnique(TEXT("python-multispeaker-narration-v1"));
	return Health;
}
