// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS7BTestInternal
{
	const FHyperTwistSkillRetainedDomainPackSkill* FindSkillById(
		const FHyperTwistSkillRetainedDomainPackState& PackState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillRetainedDomainPackSkill& Skill :
			PackState.Skills)
		{
			if (Skill.SkillId == SkillId)
			{
				return &Skill;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS7BRetainedDomainPackCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS7B.RetainedDomainPackCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS7BRetainedDomainPackCoverageTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillRetainedDomainPackState PackState =
		UHyperTwistContractLibrary::MakeSampleSkillRetainedDomainPackState();

	TestTrue(
		TEXT("The sample S7-B retained-domain-pack state should be structurally valid."),
		PackState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S7-B should expose three bounded retained domain-pack skills."),
		PackState.SkillCount,
		3
	);
	TestEqual(
		TEXT("S7-B should expose one training/replay review pack skill."),
		PackState.TrainingReplayPackSkillCount,
		1
	);
	TestEqual(
		TEXT("S7-B should expose one curriculum/content pack skill."),
		PackState.CurriculumContentPackSkillCount,
		1
	);
	TestEqual(
		TEXT("S7-B should expose one media/export pack skill."),
		PackState.MediaExportPackSkillCount,
		1
	);

	const FHyperTwistSkillRetainedDomainPackSkill* TrainingReplayPackSkill =
		HyperTwistSkillPhaseS7BTestInternal::FindSkillById(
			PackState,
			TEXT("skill/review-training-replay-pack")
		);
	TestNotNull(
		TEXT("The review-training-replay-pack skill should exist."),
		TrainingReplayPackSkill
	);
	if (TrainingReplayPackSkill != nullptr)
	{
		TestEqual(
			TEXT("The review-training-replay-pack skill should bind to the first-party retained training/replay pack service."),
			TrainingReplayPackSkill->ServiceBindingId,
			FString(TEXT("service/skills/review-training-replay-pack"))
		);
		TestTrue(
			TEXT("The review-training-replay-pack skill should declare training/replay pack mode."),
			TrainingReplayPackSkill->bReadsTrainingReplayState
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS7BBoundedRetainedPackSafetyTest,
	"HyperTwist.FirstParty.Skill.PhaseS7B.BoundedRetainedPackSafety",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS7BBoundedRetainedPackSafetyTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillRetainedDomainPackState PackState =
		UHyperTwistContractLibrary::MakeSampleSkillRetainedDomainPackState();

	TestTrue(
		TEXT("The sample S7-B retained-domain-pack state should be structurally valid."),
		PackState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("Every live S7-B skill should read authoritative first-party domain state."),
		PackState.bEveryLiveSkillReadsAuthoritativeFirstPartyDomainState
	);
	TestTrue(
		TEXT("Every live S7-B skill should keep validation-harness coverage."),
		PackState.bEveryLiveSkillHasValidationHarnessCoverage
	);
	TestTrue(
		TEXT("S7-B retained domain packs should remain structurally bounded."),
		PackState.bRetainedDomainPackLayerRemainsBounded
	);
	TestTrue(
		TEXT("S7-B retained domain packs should require the landed domain-pack framework substrate."),
		PackState.bEverySkillRequiresDomainPackFrameworkSubstrate
	);
	TestTrue(
		TEXT("S7-B retained pack claims should remain first-party grounded."),
		PackState.bRetainedPackClaimsRemainFirstPartyGrounded
	);
	TestTrue(
		TEXT("S7-B should preserve deferral for unlanded packs."),
		PackState.bUnlandedPackDeferralRemainsPreserved
	);
	TestTrue(
		TEXT("S7-B should avoid creative adjunct widening."),
		PackState.bNoCreativeAdjunctWidening
	);

	const FHyperTwistSkillRetainedDomainPackSkill* MediaExportPackSkill =
		HyperTwistSkillPhaseS7BTestInternal::FindSkillById(
			PackState,
			TEXT("skill/prepare-media-export-pack")
		);
	TestNotNull(
		TEXT("The prepare-media-export-pack skill should exist."),
		MediaExportPackSkill
	);
	if (MediaExportPackSkill != nullptr)
	{
		TestTrue(
			TEXT("The prepare-media-export-pack skill should declare media/export pack mode."),
			MediaExportPackSkill->bReadsMediaExportState
		);
		TestEqual(
			TEXT("The prepare-media-export-pack skill should depend on two landed domain-pack framework inputs."),
			MediaExportPackSkill->RequiredDomainPackFrameworkSkillCount,
			2
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS7BSerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS7B.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS7BSerializationRoundTripTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillRetainedDomainPackState PackState =
		UHyperTwistContractLibrary::MakeSampleSkillRetainedDomainPackState();

	TestTrue(
		TEXT("The sample S7-B retained-domain-pack state should be structurally valid before serialization."),
		PackState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillRetainedDomainPackStateToJson(
			PackState
		);
	TestTrue(
		TEXT("Serialized S7-B JSON should include the creative-adjunct guard field."),
		Json.Contains(TEXT("bNoCreativeAdjunctWidening"))
	);

	FHyperTwistSkillRetainedDomainPackState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S7-B retained-domain-pack JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillRetainedDomainPackStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S7-B retained-domain-pack state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S7-B skill count should match the original sample."),
		RoundTrippedState.SkillCount,
		PackState.SkillCount
	);
	TestEqual(
		TEXT("Round-tripped S7-B media/export pack count should match the original sample."),
		RoundTrippedState.MediaExportPackSkillCount,
		PackState.MediaExportPackSkillCount
	);

	return true;
}

#endif
