// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS3BTestInternal
{
	const FHyperTwistSkillRecallCompactViewSkill* FindSkillById(
		const FHyperTwistSkillRecallCompactViewState& RecallCompactViewState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillRecallCompactViewSkill& Skill :
			RecallCompactViewState.Skills)
		{
			if (Skill.SkillId == SkillId)
			{
				return &Skill;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS3BRecallCompactViewCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS3B.RecallCompactViewCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS3BRecallCompactViewCoverageTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillRecallCompactViewState RecallCompactViewState =
		UHyperTwistContractLibrary::MakeSampleSkillRecallCompactViewState();

	TestTrue(
		TEXT("The sample S3-B recall/compact-view skill state should be structurally valid."),
		RecallCompactViewState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S3-B should expose two recall/compact-view skills."),
		RecallCompactViewState.SkillCount,
		2
	);
	TestEqual(
		TEXT("S3-B should expose two live recall/compact-view skills."),
		RecallCompactViewState.LiveSkillCount,
		2
	);
	TestEqual(
		TEXT("S3-B should expose two currently available recall/compact-view skills in the sample state."),
		RecallCompactViewState.AvailableNowCount,
		2
	);

	const FHyperTwistSkillRecallCompactViewSkill* RecallMemorySkill =
		HyperTwistSkillPhaseS3BTestInternal::FindSkillById(
			RecallCompactViewState,
			TEXT("skill/recall-memory")
		);
	TestNotNull(
		TEXT("The recall-memory skill should exist."),
		RecallMemorySkill
	);
	if (RecallMemorySkill != nullptr)
	{
		TestEqual(
			TEXT("The recall-memory skill should bind to the bounded recall brief artifact."),
			RecallMemorySkill->OutputArtifactKinds[0],
			FString(TEXT("artifact/recall-memory-brief"))
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS3BAuthoritativeCompactViewLinkageTest,
	"HyperTwist.FirstParty.Skill.PhaseS3B.AuthoritativeCompactViewLinkage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS3BAuthoritativeCompactViewLinkageTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillRecallCompactViewState RecallCompactViewState =
		UHyperTwistContractLibrary::MakeSampleSkillRecallCompactViewState();

	TestTrue(
		TEXT("The sample S3-B recall/compact-view skill state should be structurally valid."),
		RecallCompactViewState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("Every live S3-B skill should read authoritative stores."),
		RecallCompactViewState.bEveryLiveSkillReadsAuthoritativeStores
	);
	TestTrue(
		TEXT("Every live S3-B skill should keep validation-harness coverage."),
		RecallCompactViewState.bEveryLiveSkillHasValidationHarnessCoverage
	);
	TestTrue(
		TEXT("S3-B compact views must remain optional and linked to authoritative sources."),
		RecallCompactViewState.bCompactViewsRemainOptionalAndLinkedToAuthoritativeSources
	);

	const FHyperTwistSkillRecallCompactViewSkill* CompactViewSkill =
		HyperTwistSkillPhaseS3BTestInternal::FindSkillById(
			RecallCompactViewState,
			TEXT("skill/generate-compact-view")
		);
	TestNotNull(
		TEXT("The generate-compact-view skill should exist."),
		CompactViewSkill
	);
	if (CompactViewSkill != nullptr)
	{
		TestTrue(
			TEXT("The generate-compact-view skill should remain an optional compact view."),
			CompactViewSkill->bOptionalCompactView
		);
		TestTrue(
			TEXT("The generate-compact-view skill should stay linked to authoritative sources."),
			CompactViewSkill->bLinkedToAuthoritativeSources
		);
		TestEqual(
			TEXT("The generate-compact-view skill should bind to the bounded compact-view artifact."),
			CompactViewSkill->OutputArtifactKinds[0],
			FString(TEXT("artifact/compact-view-brief"))
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS3BSerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS3B.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS3BSerializationRoundTripTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillRecallCompactViewState RecallCompactViewState =
		UHyperTwistContractLibrary::MakeSampleSkillRecallCompactViewState();

	TestTrue(
		TEXT("The sample S3-B recall/compact-view skill state should be structurally valid before serialization."),
		RecallCompactViewState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillRecallCompactViewStateToJson(
			RecallCompactViewState
		);
	TestTrue(
		TEXT("Serialized S3-B JSON should include the compact-view authoritative-link guard field."),
		Json.Contains(TEXT("bCompactViewsRemainOptionalAndLinkedToAuthoritativeSources"))
	);

	FHyperTwistSkillRecallCompactViewState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S3-B recall/compact-view JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillRecallCompactViewStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S3-B recall/compact-view state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S3-B skill count should match the original sample."),
		RoundTrippedState.SkillCount,
		RecallCompactViewState.SkillCount
	);
	TestEqual(
		TEXT("Round-tripped S3-B live-skill count should match the original sample."),
		RoundTrippedState.LiveSkillCount,
		RecallCompactViewState.LiveSkillCount
	);

	return true;
}

#endif
