// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"

#if WITH_AUTOMATION_TESTS

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistLearnedSearchPhase6RAVReferenceBundleTest,
	"HyperTwist.FirstParty.LearnedSearch.Phase6R.AV.ReferenceBundle",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistLearnedSearchPhase6RAVReferenceBundleTest::RunTest(const FString& Parameters)
{
	const FHyperTwistTrainingLearnedSearchReferenceBundle Bundle =
		UHyperTwistTrainingRuntimeLibrary::GetBundledLearnedSearchReferenceBundle();

	TestTrue(TEXT("The learned-search bundle must remain structurally valid after Phase 6R-AV."), Bundle.IsStructurallyValid());
	TestEqual(
		TEXT("The primary learned-search experiment profile id must stay stable."),
		Bundle.PrimaryExperimentProfileContractId,
		TEXT("learned-search-experiment-profile")
	);
	TestTrue(
		TEXT("The learned-search bundle must keep the ADI benchmark package reference."),
		Bundle.PackageReferences.ContainsByPredicate(
			[](const FHyperTwistTrainingLearnedSearchPackageReference& Reference)
			{
				return Reference.PackageId == TEXT("package/yakupbilen-adi-train-utils")
					&& Reference.SourceAttribution.SourceRepo == TEXT("yakupbilen/drl-rubiks-cube");
			}
		)
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistLearnedSearchPhase6RAVExperimentProfileTest,
	"HyperTwist.FirstParty.LearnedSearch.Phase6R.AV.ExperimentProfile",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistLearnedSearchPhase6RAVExperimentProfileTest::RunTest(const FString& Parameters)
{
	FHyperTwistTrainingLearnedSearchExperimentProfileContract Contract;
	TestTrue(
		TEXT("The learned-search experiment profile must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledLearnedSearchExperimentProfileContract(
			TEXT("learned-search-experiment-profile"),
			Contract
		)
	);
	TestEqual(
		TEXT("The learned-search experiment profile id must stay stable."),
		Contract.ContractId,
		TEXT("learned-search-experiment-profile")
	);
	TestEqual(
		TEXT("The learned-search experiment profile must remain first-party."),
		Contract.SourceAttribution.SourceMode,
		EHyperTwistTrainingSourceMode::FirstParty
	);
	TestTrue(
		TEXT("The learned-search experiment profile must require the compact state package."),
		Contract.RequiredPackageIds.Contains(TEXT("package/yakupbilen-cube-state"))
	);
	TestTrue(
		TEXT("The learned-search experiment profile must require the ADI generation package."),
		Contract.RequiredPackageIds.Contains(TEXT("package/yakupbilen-adi-train-utils"))
	);
	TestTrue(
		TEXT("The learned-search experiment profile must preserve batched neural A* frontier scoring."),
		Contract.SearchSurfaceTags.Contains(TEXT("batched neural A* frontier scoring"))
	);
	TestTrue(
		TEXT("The learned-search experiment profile must keep correctness/performance oracle ownership excluded."),
		Contract.ExplicitExclusions.Contains(TEXT("correctness/performance oracle ownership"))
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistLearnedSearchPhase6RAVBoundaryTest,
	"HyperTwist.FirstParty.LearnedSearch.Phase6R.AV.Boundaries",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistLearnedSearchPhase6RAVBoundaryTest::RunTest(const FString& Parameters)
{
	FHyperTwistTrainingLearnedSearchSearchBenchmarkBoundary SearchBoundary;
	TestTrue(
		TEXT("The learned-search benchmark boundary must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledLearnedSearchSearchBenchmarkBoundary(
			TEXT("learned-search-search-benchmark-boundary"),
			SearchBoundary
		)
	);
	TestTrue(
		TEXT("The benchmark boundary must require the neural search package."),
		SearchBoundary.RequiredPackageIds.Contains(TEXT("package/yakupbilen-search"))
	);
	TestTrue(
		TEXT("The benchmark boundary must preserve small value-network inference."),
		SearchBoundary.ModelSurfaceTags.Contains(TEXT("small value-network inference"))
	);
	TestTrue(
		TEXT("The benchmark boundary must keep live recognition/reconstruction ownership caveats visible."),
		SearchBoundary.ProvenanceCaveats.Contains(TEXT("qbr and rubix-cube-solver remain live recognition/reconstruction owners"))
	);

	FHyperTwistTrainingLearnedSearchAttributionBoundary AttributionBoundary;
	TestTrue(
		TEXT("The learned-search attribution boundary must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledLearnedSearchAttributionBoundary(
			TEXT("learned-search-attribution-boundary"),
			AttributionBoundary
		)
	);
	TestTrue(
		TEXT("The attribution boundary must preserve first-party reauthored experimentation use."),
		AttributionBoundary.AllowedUseTags.Contains(TEXT("first-party reauthored experimentation lane"))
	);
	TestTrue(
		TEXT("The attribution boundary must keep silent donor promotion excluded."),
		AttributionBoundary.ExplicitExclusions.Contains(TEXT("silent donor promotion"))
	);
	return true;
}

#endif
