// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"

#if WITH_AUTOMATION_TESTS

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistHyperspeedcubePhase6RNDslContractTest,
	"HyperTwist.Permissive.Hyperspeedcube.Phase6R.N.DslContract",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistHyperspeedcubePhase6RNDslContractTest::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() >= 20
	);

	FHyperTwistTrainingHyperspeedcubeDslContract Contract;
	TestTrue(
		TEXT("The Hyperspeedcube DSL contract must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledHyperspeedcubeDslContract(
			Bundle.PrimaryDslContractId,
			Contract
		)
	);
	TestEqual(
		TEXT("The DSL contract id must stay stable."),
		Contract.ContractId,
		TEXT("hyperspeedcube-dsl-authoring-contract")
	);
	TestTrue(
		TEXT("The DSL contract must require the retained parser package."),
		Contract.RequiredPackageIds.Contains(TEXT("package/hyperspeedcube-hps-parser"))
	);
	TestTrue(
		TEXT("The DSL contract must preserve string interpolation parsing."),
		Contract.SyntaxSurfaceTags.Contains(TEXT("string interpolation parse"))
	);
	TestTrue(
		TEXT("The DSL contract must preserve generator authoring builtins."),
		Contract.GeneratorAuthoringSurfaceTags.Contains(TEXT("add_puzzle_generator built-in"))
	);
	TestTrue(
		TEXT("The DSL contract must keep runtime-anchor ownership excluded."),
		Contract.ExplicitExclusions.Contains(TEXT("whole runtime-anchor ownership"))
	);
	TestEqual(
		TEXT("The DSL contract must keep the direct donor source repo."),
		Contract.SourceAttribution.SourceRepo,
		TEXT("HactarCE/Hyperspeedcube")
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistHyperspeedcubePhase6RNDslBoundaryTest,
	"HyperTwist.Permissive.Hyperspeedcube.Phase6R.N.DslBoundary",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

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

	FHyperTwistTrainingHyperspeedcubeDslBoundary Boundary;
	TestTrue(
		TEXT("The Hyperspeedcube DSL boundary must resolve from the runtime library."),
		UHyperTwistTrainingRuntimeLibrary::TryGetBundledHyperspeedcubeDslBoundary(
			Bundle.PrimaryDslBoundaryId,
			Boundary
		)
	);
	TestEqual(
		TEXT("The DSL boundary id must stay stable."),
		Boundary.BoundaryId,
		TEXT("hyperspeedcube-dsl-module-evaluation-boundary")
	);
	TestTrue(
		TEXT("The DSL boundary must preserve index-file folding."),
		Boundary.ModuleSurfaceTags.Contains(TEXT("index-file folding"))
	);
	TestTrue(
		TEXT("The DSL boundary must preserve the non-reentrant eval rule."),
		Boundary.EvaluationSurfaceTags.Contains(TEXT("non-reentrant eval rule"))
	);
	TestTrue(
		TEXT("The DSL boundary must preserve the file-custody provenance caveat."),
		Boundary.ProvenanceCaveats.Contains(TEXT("the donor module tree may load user files from a donor-configured path, but HyperTwist keeps top-level file custody first-party"))
	);
	TestTrue(
		TEXT("The DSL boundary must keep generic background job ownership excluded."),
		Boundary.ExplicitExclusions.Contains(TEXT("generic background job system ownership"))
	);
	return true;
}

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

bool FHyperTwistHyperspeedcubePhase6RNPackageChecklistTest::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 DSL parser package id."),
		Checklist.Contains(TEXT("package/hyperspeedcube-hps-parser"))
	);
	TestTrue(
		TEXT("The checklist must preserve the puzzle builtin export path."),
		Checklist.Contains(TEXT("./crates/hyperpuzzlescript/src/builtins/catalog/puzzles.rs"))
	);
	TestTrue(
		TEXT("The checklist must preserve the FT cube builtin example path."),
		Checklist.Contains(TEXT("./hps/puzzles/ft_cube.hps"))
	);
	TestTrue(
		TEXT("The checklist must preserve the direct dual-license donor posture."),
		Checklist.Contains(TEXT("direct dual-license donor"))
	);
	return true;
}

#endif
