// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"
#include "HyperTwistRecognition/HyperTwistVoiceClient.h"
#include "UObject/Object.h"

#if WITH_AUTOMATION_TESTS

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

	UHyperTwistHttpVoiceClient* MakeHttpVoiceClient()
	{
		return NewObject<UHyperTwistHttpVoiceClient>();
	}

	const FHyperTwistVoiceModelReviewDescriptor* FindReviewById(
		const TArray<FHyperTwistVoiceModelReviewDescriptor>& Reviews,
		const FString& ReviewId
	)
	{
		return Reviews.FindByPredicate(
			[&ReviewId](const FHyperTwistVoiceModelReviewDescriptor& Review)
			{
				return Review.VoiceModelReviewId == ReviewId;
			}
		);
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoquiPhase6RARVoiceModelReviewProfileTest,
	"HyperTwist.Permissive.Coqui.Phase6R.AR.VoiceModelReviewProfile",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

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

	const FHyperTwistVoiceServiceHealth Health = VoiceClient->GetVoiceServiceHealth();
	TestTrue(TEXT("The advanced voice-model review health must remain structurally valid."), Health.IsStructurallyValid());
	TestEqual(
		TEXT("The advanced review lane must preserve the voice-model review profile id."),
		Health.VoiceModelReviewProfileId,
		TEXT("downloadable-voice-model-review-v1")
	);
	TestTrue(
		TEXT("The advanced review profile must remain structurally valid."),
		Health.VoiceModelReviewProfileDefinition.IsStructurallyValid()
	);
	TestTrue(
		TEXT("The advanced review lane must advertise downloadable voice-model review."),
		Health.Capabilities.Contains(TEXT("downloadableVoiceModelReview"))
	);
	TestTrue(
		TEXT("The advanced review lane must advertise model-license selection review."),
		Health.Capabilities.Contains(TEXT("modelLicenseSelectionReview"))
	);
	TestTrue(
		TEXT("The advanced review lane must advertise terms-acceptance review."),
		Health.Capabilities.Contains(TEXT("termsAcceptanceReview"))
	);
	TestFalse(
		TEXT("The advanced review profile must keep runtime model download deferred."),
		Health.VoiceModelReviewProfileDefinition.bAllowsRuntimeModelDownloadInCurrentPacket
	);
	TestFalse(
		TEXT("The advanced review profile must keep bundled model redistribution disabled."),
		Health.VoiceModelReviewProfileDefinition.bAllowsBundledModelRedistribution
	);
	TestEqual(
		TEXT("The advanced review lane must expose one bounded advanced review descriptor."),
		Health.SupportedVoiceModelReviewIds.Num(),
		1
	);
	TestEqual(
		TEXT("The advanced review lane must expose one bounded advanced review record."),
		Health.SupportedVoiceModelReviews.Num(),
		1
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoquiPhase6RARAdvancedNarrationReviewAlignmentTest,
	"HyperTwist.Permissive.Coqui.Phase6R.AR.AdvancedNarrationReviewAlignment",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

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

	const FHyperTwistVoiceServiceHealth Health = VoiceClient->GetVoiceServiceHealth();
	const FHyperTwistNarrationSynthesisRequest Request =
		UHyperTwistContractLibrary::MakeSampleAdvancedNarrationSynthesisRequest();
	const FHyperTwistVoiceModelReviewDescriptor* Review =
		HyperTwistCoquiPhase6RARTestInternal::FindReviewById(
			Health.SupportedVoiceModelReviews,
			TEXT("voice-model-review/coqui/multilingual-premium-v1")
		);
	TestNotNull(TEXT("The advanced coqui review descriptor must be present."), Review);
	if (Review == nullptr)
	{
		return false;
	}

	TestEqual(
		TEXT("The review descriptor must align to the advanced narration model binding."),
		Review->ModelBindingId,
		Request.OrchestrationProfile.ModelBindingId
	);
	TestEqual(
		TEXT("The review descriptor must align to the advanced narration vocoder binding."),
		Review->VocoderBindingId,
		Request.OrchestrationProfile.VocoderBindingId
	);
	TestEqual(
		TEXT("The review descriptor must align to the advanced narration voice profile."),
		Review->VoiceProfileId,
		Request.VoiceProfileId
	);
	TestEqual(
		TEXT("The review descriptor must preserve the registry-backed review document path."),
		Review->ReviewDocumentPath,
		TEXT("TTS/.models.json")
	);
	TestTrue(
		TEXT("The advanced descriptor must preserve the terms-acceptance review requirement."),
		Review->bTosAcceptanceRequired
	);
	TestFalse(
		TEXT("The advanced descriptor must not imply bundled redistribution."),
		Review->bBundledWithCodeDistribution
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoquiPhase6RARProviderBackedReviewFallbackTest,
	"HyperTwist.Permissive.Coqui.Phase6R.AR.ProviderBackedReviewFallback",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoquiPhase6RARProviderBackedReviewFallbackTest::RunTest(const FString& Parameters)
{
	UHyperTwistHttpVoiceClient* VoiceClient = HyperTwistCoquiPhase6RARTestInternal::MakeHttpVoiceClient();
	TestNotNull(TEXT("The provider-backed voice client must be constructed for Phase 6R-AR."), VoiceClient);
	if (VoiceClient == nullptr)
	{
		return false;
	}

	VoiceClient->ServiceBaseUrl.Reset();
	const FHyperTwistVoiceServiceHealth Health = VoiceClient->GetVoiceServiceHealth();

	TestTrue(TEXT("The provider-backed review fallback must remain structurally valid."), Health.IsStructurallyValid());
	TestFalse(TEXT("The provider-backed review fallback must report not ready."), Health.bReady);
	TestEqual(
		TEXT("The provider-backed review fallback must preserve the missing-endpoint error."),
		Health.LastError,
		TEXT("service-base-url-missing")
	);
	TestTrue(
		TEXT("The provider-backed review fallback must preserve downloadable voice-model review capability."),
		Health.Capabilities.Contains(TEXT("downloadableVoiceModelReview"))
	);
	TestEqual(
		TEXT("The provider-backed review fallback must preserve one advanced review id."),
		Health.SupportedVoiceModelReviewIds.Num(),
		1
	);
	TestEqual(
		TEXT("The provider-backed review fallback must preserve one advanced review descriptor."),
		Health.SupportedVoiceModelReviews.Num(),
		1
	);
	return true;
}

#endif
