// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"

#if WITH_AUTOMATION_TESTS

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistHyperspeedcubePhase6RMStatsShapeContractTest,
	"HyperTwist.Permissive.Hyperspeedcube.Phase6R.M.StatsShapeContract",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistHyperspeedcubePhase6RMStatsShapeContractTest::RunTest(const FString& Parameters)
{
	const FHyperTwistTrainingHyperspeedcubeReferenceBundle Bundle =
		UHyperTwistTrainingRuntimeLibrary::GetBundledHyperspeedcubeReferenceBundle();

	TestTrue(TEXT("The Hyperspeedcube bundle must stay structurally valid."), Bundle.IsStructurallyValid());
	TestTrue(
		TEXT("The Hyperspeedcube bundle must preserve the expanded donor package set."),
		Bundle.PackageReferences.Num() >= 11
	);

	FHyperTwistTrainingHyperspeedcubeStatsShapeContract Contract;
	TestTrue(
		TEXT("The Hyperspeedcube stats-shape contract must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledHyperspeedcubeStatsShapeContract(
			Bundle.PrimaryStatsShapeContractId,
			Contract
		)
	);
	TestEqual(
		TEXT("The stats-shape contract id must stay stable."),
		Contract.ContractId,
		TEXT("hyperspeedcube-stats-shape-contract")
	);
	TestTrue(
		TEXT("The stats-shape contract must require the retained stats DB package."),
		Contract.RequiredPackageIds.Contains(TEXT("package/hyperspeedcube-stats-db"))
	);
	TestTrue(
		TEXT("The stats-shape contract must preserve the speed PB category."),
		Contract.StatCategorySurfaceTags.Contains(TEXT("speed PB category"))
	);
	TestTrue(
		TEXT("The stats-shape contract must preserve the used_macros qualifier."),
		Contract.QualifierSurfaceTags.Contains(TEXT("used_macros qualifier"))
	);
	TestTrue(
		TEXT("The stats-shape contract must preserve the verified completion timestamp."),
		Contract.SolveProofSurfaceTags.Contains(TEXT("verified completion timestamp"))
	);
	TestTrue(
		TEXT("The stats-shape contract must keep analytics dashboard ownership excluded."),
		Contract.ExplicitExclusions.Contains(TEXT("analytics dashboard ownership"))
	);
	TestEqual(
		TEXT("The stats-shape contract must keep the direct donor source repo."),
		Contract.SourceAttribution.SourceRepo,
		TEXT("HactarCE/Hyperspeedcube")
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistHyperspeedcubePhase6RMSolveRecordBoundaryTest,
	"HyperTwist.Permissive.Hyperspeedcube.Phase6R.M.SolveRecordBoundary",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistHyperspeedcubePhase6RMSolveRecordBoundaryTest::RunTest(const FString& Parameters)
{
	const FHyperTwistTrainingHyperspeedcubeReferenceBundle Bundle =
		UHyperTwistTrainingRuntimeLibrary::GetBundledHyperspeedcubeReferenceBundle();

	FHyperTwistTrainingHyperspeedcubeSolveRecordBoundary Boundary;
	TestTrue(
		TEXT("The Hyperspeedcube solve-record boundary must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledHyperspeedcubeSolveRecordBoundary(
			Bundle.PrimarySolveRecordBoundaryId,
			Boundary
		)
	);
	TestEqual(
		TEXT("The solve-record boundary id must stay stable."),
		Boundary.BoundaryId,
		TEXT("hyperspeedcube-solve-record-boundary")
	);
	TestTrue(
		TEXT("The solve-record boundary must preserve solve-log file association."),
		Boundary.RecordShapeSurfaceTags.Contains(TEXT("solve-log file association"))
	);
	TestTrue(
		TEXT("The solve-record boundary must preserve the blind PB duration field."),
		Boundary.PersonalBestSurfaceTags.Contains(TEXT("blind PB duration"))
	);
	TestTrue(
		TEXT("The solve-record boundary must preserve the bounded KDL persistence caveat."),
		Boundary.ProvenanceCaveats.Contains(TEXT("the donor stats serialization format is a bounded KDL persistence seam rather than HyperTwist's whole repository contract"))
	);
	TestTrue(
		TEXT("The solve-record boundary must keep publication ownership excluded."),
		Boundary.ExplicitExclusions.Contains(TEXT("publication/leaderboard ownership"))
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistHyperspeedcubePhase6RMPackageChecklistTest,
	"HyperTwist.Permissive.Hyperspeedcube.Phase6R.M.PackageChecklist",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistHyperspeedcubePhase6RMPackageChecklistTest::RunTest(const FString& Parameters)
{
	const FString Checklist = UHyperTwistTrainingRuntimeLibrary::BuildBundledHyperspeedcubePackageChecklistTsv();
	TestTrue(TEXT("The Hyperspeedcube package checklist must not be empty."), !Checklist.IsEmpty());
	TestTrue(
		TEXT("The checklist must preserve the stats DB package id."),
		Checklist.Contains(TEXT("package/hyperspeedcube-stats-db"))
	);
	TestTrue(
		TEXT("The checklist must preserve the solve-summary export path."),
		Checklist.Contains(TEXT("./crates/hyperspeedcube/src/gui/modals/solve_summary.rs"))
	);
	TestTrue(
		TEXT("The checklist must preserve the direct dual-license donor posture."),
		Checklist.Contains(TEXT("direct dual-license donor"))
	);
	return true;
}

#endif
