// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"
#include "HyperTwistMemory/HyperTwistMemoryCoreLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistMemoryPhase6RM6TestInternal
{
	const FHyperTwistMemoryCompactSummary* FindCompactSummaryByKind(
		const FHyperTwistMemoryDerivedAdjunctState& DerivedAdjunctState,
		const FString& SummaryKind
	)
	{
		for (const FHyperTwistMemoryCompactSummary& CompactSummary :
			DerivedAdjunctState.CompactSummaries)
		{
			if (CompactSummary.SummaryKind == SummaryKind)
			{
				return &CompactSummary;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistMemoryPhase6RM6ActiveDerivedViewsTest,
	"HyperTwist.FirstParty.Memory.Phase6R.M6.ActiveDerivedViews",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistMemoryPhase6RM6ActiveDerivedViewsTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistMemoryDerivedAdjunctState DerivedAdjunctState =
		UHyperTwistContractLibrary::MakeSampleTrainingMemoryDerivedAdjunctState();

	TestTrue(
		TEXT("The Phase 6R-M6 derived-adjunct state must be structurally valid."),
		DerivedAdjunctState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The sample M6 state must derive from max-retention mode."),
		DerivedAdjunctState.ContextAssemblyProfile,
		EHyperTwistMemoryContextAssemblyProfile::MaxRetentionMode
	);
	TestEqual(
		TEXT("The M6 state must bind to the canonical derived-compacted feature gate."),
		DerivedAdjunctState.FeatureGateId,
		TEXT("memory-gate/derived-compacted")
	);
	TestTrue(
		TEXT("The max-retention sample must keep derived adjuncts active."),
		DerivedAdjunctState.bDerivedGateActive
	);
	TestTrue(
		TEXT("The active M6 state must expose compact summaries."),
		DerivedAdjunctState.CompactSummaryCount > 0
	);
	TestTrue(
		TEXT("The active M6 state must expose reduced context packets."),
		DerivedAdjunctState.ReducedContextPacketCount > 0
	);
	TestTrue(
		TEXT("The active M6 state must expose digest views."),
		DerivedAdjunctState.DigestViewCount > 0
	);

	const FHyperTwistMemoryCompactSummary* OverviewSummary =
		HyperTwistMemoryPhase6RM6TestInternal::FindCompactSummaryByKind(
			DerivedAdjunctState,
			TEXT("memory-overview")
		);
	TestNotNull(
		TEXT("A memory-overview compact summary must exist."),
		OverviewSummary
	);
	if (OverviewSummary != nullptr)
	{
		TestEqual(
			TEXT("Compact summaries must stay in the derived-compacted lane."),
			OverviewSummary->Lane,
			EHyperTwistMemoryLane::DerivedCompacted
		);
		TestEqual(
			TEXT("Compact summaries must remain derived-only."),
			OverviewSummary->AuthorityKind,
			EHyperTwistMemoryAuthorityKind::DerivedOnly
		);
		TestTrue(
			TEXT("Compact summaries must preserve provenance."),
			OverviewSummary->ProvenanceLinks.Num() > 0
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistMemoryPhase6RM6AllFeaturesOffCorrectnessTest,
	"HyperTwist.FirstParty.Memory.Phase6R.M6.AllFeaturesOffCorrectness",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistMemoryPhase6RM6AllFeaturesOffCorrectnessTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistTrainingRepositoryState RepositoryState =
		UHyperTwistContractLibrary::MakeSampleTrainingRepositoryState();
	const FHyperTwistMemoryDerivedAdjunctState DerivedAdjunctState =
		UHyperTwistMemoryCoreLibrary::DeriveMemoryDerivedAdjunctState(
			RepositoryState,
			TEXT("local-user"),
			TEXT("2026-04-28T12:40:00Z"),
			EHyperTwistMemoryContextAssemblyProfile::EconomicRetentionMode
		);

	TestTrue(
		TEXT("The all-features-off M6 state must remain structurally valid."),
		DerivedAdjunctState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The all-features-off test must use economic-retention mode."),
		DerivedAdjunctState.ContextAssemblyProfile,
		EHyperTwistMemoryContextAssemblyProfile::EconomicRetentionMode
	);
	TestFalse(
		TEXT("Economic-retention mode must keep derived adjuncts disabled by default."),
		DerivedAdjunctState.bDerivedGateActive
	);
	TestEqual(
		TEXT("The disabled M6 state must expose zero compact summaries."),
		DerivedAdjunctState.CompactSummaryCount,
		0
	);
	TestEqual(
		TEXT("The disabled M6 state must expose zero reduced context packets."),
		DerivedAdjunctState.ReducedContextPacketCount,
		0
	);
	TestEqual(
		TEXT("The disabled M6 state must expose zero digest views."),
		DerivedAdjunctState.DigestViewCount,
		0
	);
	TestTrue(
		TEXT("The M6 state must confirm derived-only storage."),
		DerivedAdjunctState.bDerivedOnlyStorageConfirmed
	);
	TestTrue(
		TEXT("The M6 state must confirm removability without lineage loss."),
		DerivedAdjunctState.bRemovableWithoutLineageLoss
	);
	TestTrue(
		TEXT("The M6 state must confirm all-features-off correctness."),
		DerivedAdjunctState.bAllFeaturesOffSafe
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistMemoryPhase6RM6SerializationRoundTripTest,
	"HyperTwist.FirstParty.Memory.Phase6R.M6.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistMemoryPhase6RM6SerializationRoundTripTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistMemoryDerivedAdjunctState DerivedAdjunctState =
		UHyperTwistContractLibrary::MakeSampleTrainingMemoryDerivedAdjunctState();
	TestTrue(
		TEXT("The Phase 6R-M6 derived-adjunct state must be structurally valid."),
		DerivedAdjunctState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeMemoryDerivedAdjunctStateToJson(
			DerivedAdjunctState
		);
	TestFalse(TEXT("The serialized M6 JSON must not be empty."), Json.IsEmpty());
	TestTrue(
		TEXT("The serialized M6 JSON must expose digest views."),
		Json.Contains(TEXT("DigestViews"))
	);

	FHyperTwistMemoryDerivedAdjunctState RoundTrippedState;
	TestTrue(
		TEXT("The M6 JSON must deserialize cleanly."),
		UHyperTwistContractLibrary::DeserializeMemoryDerivedAdjunctStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("The round-tripped M6 state must remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The round-tripped M6 state must preserve compact-summary counts."),
		RoundTrippedState.CompactSummaryCount,
		DerivedAdjunctState.CompactSummaryCount
	);
	TestEqual(
		TEXT("The round-tripped M6 state must preserve reduced-context counts."),
		RoundTrippedState.ReducedContextPacketCount,
		DerivedAdjunctState.ReducedContextPacketCount
	);
	TestEqual(
		TEXT("The round-tripped M6 state must preserve digest-view counts."),
		RoundTrippedState.DigestViewCount,
		DerivedAdjunctState.DigestViewCount
	);
	TestEqual(
		TEXT("The round-tripped M6 state must preserve gate activation."),
		RoundTrippedState.bDerivedGateActive,
		DerivedAdjunctState.bDerivedGateActive
	);

	return true;
}

#endif
