// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"
#include "HyperTwistRecognition/HyperTwistVoiceClient.h"
#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistCoquiPhase6RHTestInternal
{
	UHyperTwistMockVoiceClient* MakeMockVoiceClient()
	{
		return NewObject<UHyperTwistMockVoiceClient>();
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoquiPhase6RHAdvancedNarrationRequestTest,
	"HyperTwist.Permissive.Coqui.Phase6R.H.AdvancedNarrationRequest",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoquiPhase6RHAdvancedNarrationRequestTest::RunTest(const FString& Parameters)
{
	FHyperTwistTrainingCompanionNarrationContract NarrationContract;
	TestTrue(
		TEXT("The bundled embodied companion narration contract must stay available for Phase 6R-H."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledEmbodiedCompanionNarrationContract(
			TEXT("embodied-companion-narration"),
			NarrationContract
		)
	);
	TestTrue(TEXT("The bundled narration contract must remain structurally valid."), NarrationContract.IsStructurallyValid());

	UHyperTwistMockVoiceClient* VoiceClient = HyperTwistCoquiPhase6RHTestInternal::MakeMockVoiceClient();
	TestNotNull(TEXT("The mock voice client must be constructed for Phase 6R-H."), VoiceClient);
	if (VoiceClient == nullptr)
	{
		return false;
	}

	const TArray<FHyperTwistVoiceProfileSummary> Profiles = VoiceClient->ListVoiceProfiles();
	TestTrue(TEXT("The retained advanced narration slice must expose a multilingual guide profile."), Profiles.ContainsByPredicate(
		[](const FHyperTwistVoiceProfileSummary& Profile)
		{
			return Profile.VoiceProfileId == TEXT("multilingual-guide-premium")
				&& Profile.NumSpeakers >= 2;
		}
	));

	const FHyperTwistNarrationSynthesisRequest Request =
		UHyperTwistContractLibrary::MakeSampleAdvancedNarrationSynthesisRequest();
	TestTrue(TEXT("The advanced narration request must be structurally valid."), Request.IsStructurallyValid());
	TestEqual(
		TEXT("The advanced request must stay on the embodied companion narration contract."),
		Request.NarrationContractId,
		TEXT("embodied-companion-narration")
	);
	TestEqual(
		TEXT("The advanced request must move to the Python voice service lane."),
		Request.ServiceLaneId,
		TEXT("voice/python-service")
	);
	TestEqual(
		TEXT("The advanced orchestration profile must be bounded to the retained multispeaker narration slice."),
		Request.OrchestrationProfile.OrchestrationProfileId,
		TEXT("python-multispeaker-narration-v1")
	);
	TestEqual(
		TEXT("The advanced request must carry the normalized narration model binding."),
		Request.OrchestrationProfile.ModelBindingId,
		TEXT("voice-model/multilingual-premium-v1")
	);
	TestEqual(
		TEXT("The advanced request must carry the normalized vocoder binding."),
		Request.OrchestrationProfile.VocoderBindingId,
		TEXT("vocoder/high-fidelity-v1")
	);
	TestTrue(TEXT("The advanced request must enable speaker selection."), Request.OrchestrationProfile.bEnableSpeakerSelection);
	TestTrue(TEXT("The advanced request must enable language routing."), Request.OrchestrationProfile.bEnableLanguageRouting);
	TestTrue(TEXT("The advanced request must enable sentence splitting."), Request.bSplitSentences);
	TestTrue(
		TEXT("The advanced request must retain a reference-voice sample ref without making voice assets part of the packet."),
		!Request.ReferenceVoiceSampleRef.IsEmpty()
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoquiPhase6RHAdvancedNarrationResultTest,
	"HyperTwist.Permissive.Coqui.Phase6R.H.AdvancedNarrationResult",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoquiPhase6RHAdvancedNarrationResultTest::RunTest(const FString& Parameters)
{
	UHyperTwistMockVoiceClient* VoiceClient = HyperTwistCoquiPhase6RHTestInternal::MakeMockVoiceClient();
	TestNotNull(TEXT("The mock voice client must be constructed for Phase 6R-H."), VoiceClient);
	if (VoiceClient == nullptr)
	{
		return false;
	}

	const FHyperTwistNarrationSynthesisRequest Request =
		UHyperTwistContractLibrary::MakeSampleAdvancedNarrationSynthesisRequest();
	const FHyperTwistNarrationSynthesisResult Result = VoiceClient->SynthesizeNarration(Request);

	TestTrue(TEXT("The advanced narration synthesis result must stay structurally valid."), Result.IsStructurallyValid());
	TestEqual(TEXT("The advanced result must preserve the request id."), Result.RequestId, Request.RequestId);
	TestEqual(
		TEXT("The advanced result must preserve the advanced orchestration profile id."),
		Result.OrchestrationProfileId,
		Request.OrchestrationProfile.OrchestrationProfileId
	);
	TestEqual(TEXT("The advanced result must stay on the Python voice service lane."), Result.ServiceLaneId, TEXT("voice/python-service"));
	TestEqual(
		TEXT("The advanced result must preserve the normalized narration model binding."),
		Result.ModelBindingId,
		Request.OrchestrationProfile.ModelBindingId
	);
	TestEqual(
		TEXT("The advanced result must preserve the normalized vocoder binding."),
		Result.VocoderBindingId,
		Request.OrchestrationProfile.VocoderBindingId
	);
	TestEqual(
		TEXT("The advanced result must preserve the selected speaker profile."),
		Result.SpeakerProfileId,
		Request.SpeakerProfileId
	);
	TestTrue(TEXT("The advanced result must report sentence splitting usage."), Result.bUsedSentenceSplitting);
	TestTrue(TEXT("The advanced result must report speaker selection usage."), Result.bUsedSpeakerSelection);
	TestTrue(
		TEXT("The advanced result must report reference-voice conditioning usage."),
		Result.bUsedSpeakerReferenceConditioning
	);
	TestEqual(
		TEXT("The advanced result must preserve subtitle text."),
		Result.SubtitleText,
		Request.SubtitleSeedText
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoquiPhase6RHServiceHealthTest,
	"HyperTwist.Permissive.Coqui.Phase6R.H.ServiceHealth",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoquiPhase6RHServiceHealthTest::RunTest(const FString& Parameters)
{
	UHyperTwistMockVoiceClient* VoiceClient = HyperTwistCoquiPhase6RHTestInternal::MakeMockVoiceClient();
	TestNotNull(TEXT("The mock voice client must be constructed for Phase 6R-H."), VoiceClient);
	if (VoiceClient == nullptr)
	{
		return false;
	}

	const FHyperTwistVoiceServiceHealth Health = VoiceClient->GetVoiceServiceHealth();
	TestTrue(TEXT("The advanced voice service health must be structurally valid."), Health.IsStructurallyValid());
	TestTrue(TEXT("The advanced voice service health must report ready."), Health.bReady);
	TestTrue(TEXT("The advanced voice service must expose multispeaker narration capability."), Health.Capabilities.Contains(TEXT("multiSpeakerNarration")));
	TestTrue(TEXT("The advanced voice service must expose multilingual narration capability."), Health.Capabilities.Contains(TEXT("multiLingualNarration")));
	TestTrue(
		TEXT("The advanced voice service must expose speaker-reference conditioning capability."),
		Health.Capabilities.Contains(TEXT("speakerReferenceConditioning"))
	);
	TestTrue(TEXT("The advanced voice service must expose sentence-split narration capability."), Health.Capabilities.Contains(TEXT("sentenceSplitNarration")));
	TestTrue(TEXT("The advanced voice service must expose model-binding selection capability."), Health.Capabilities.Contains(TEXT("modelBindingSelection")));
	TestTrue(TEXT("The advanced voice service must expose vocoder-binding selection capability."), Health.Capabilities.Contains(TEXT("vocoderBindingSelection")));
	TestTrue(
		TEXT("The advanced voice service must advertise the retained advanced orchestration profile."),
		Health.SupportedOrchestrationProfiles.Contains(TEXT("python-multispeaker-narration-v1"))
	);
	TestTrue(
		TEXT("The advanced voice service must advertise the normalized premium narration model binding."),
		Health.SupportedModelBindingIds.Contains(TEXT("voice-model/multilingual-premium-v1"))
	);
	TestTrue(
		TEXT("The advanced voice service must advertise the normalized high-fidelity vocoder binding."),
		Health.SupportedVocoderBindingIds.Contains(TEXT("vocoder/high-fidelity-v1"))
	);
	return true;
}

#endif
