// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS7ATestInternal
{
	const FHyperTwistSkillDomainPackFrameworkSkill* FindSkillById(
		const FHyperTwistSkillDomainPackFrameworkState& FrameworkState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillDomainPackFrameworkSkill& Skill :
			FrameworkState.Skills)
		{
			if (Skill.SkillId == SkillId)
			{
				return &Skill;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS7ADomainPackFrameworkCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS7A.DomainPackFrameworkCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS7ADomainPackFrameworkCoverageTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillDomainPackFrameworkState FrameworkState =
		UHyperTwistContractLibrary::MakeSampleSkillDomainPackFrameworkState();

	TestTrue(
		TEXT("The sample S7-A domain-pack framework state should be structurally valid."),
		FrameworkState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S7-A should expose two bounded domain-pack framework skills."),
		FrameworkState.SkillCount,
		2
	);
	TestEqual(
		TEXT("S7-A should expose one packaging-rules skill."),
		FrameworkState.PackagingRuleSkillCount,
		1
	);
	TestEqual(
		TEXT("S7-A should expose one enable/disable-grouping skill."),
		FrameworkState.EnableDisableGroupingSkillCount,
		1
	);

	const FHyperTwistSkillDomainPackFrameworkSkill* PackagingSkill =
		HyperTwistSkillPhaseS7ATestInternal::FindSkillById(
			FrameworkState,
			TEXT("skill/specify-domain-packaging")
		);
	TestNotNull(
		TEXT("The specify-domain-packaging skill should exist."),
		PackagingSkill
	);
	if (PackagingSkill != nullptr)
	{
		TestEqual(
			TEXT("The specify-domain-packaging skill should bind to the first-party domain-packaging service."),
			PackagingSkill->ServiceBindingId,
			FString(TEXT("service/skills/specify-domain-packaging"))
		);
		TestTrue(
			TEXT("The specify-domain-packaging skill should declare packaging-rules mode."),
			PackagingSkill->bSpecifiesPackagingRules
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS7ABoundedFrameworkSafetyTest,
	"HyperTwist.FirstParty.Skill.PhaseS7A.BoundedFrameworkSafety",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS7ABoundedFrameworkSafetyTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillDomainPackFrameworkState FrameworkState =
		UHyperTwistContractLibrary::MakeSampleSkillDomainPackFrameworkState();

	TestTrue(
		TEXT("The sample S7-A domain-pack framework state should be structurally valid."),
		FrameworkState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("Every live S7-A skill should read authoritative skill and framework state."),
		FrameworkState.bEveryLiveSkillReadsAuthoritativeSkillAndFrameworkState
	);
	TestTrue(
		TEXT("Every live S7-A skill should keep validation-harness coverage."),
		FrameworkState.bEveryLiveSkillHasValidationHarnessCoverage
	);
	TestTrue(
		TEXT("S7-A domain-pack framework skills should remain structurally bounded."),
		FrameworkState.bDomainPackFrameworkRemainsBounded
	);
	TestTrue(
		TEXT("S7-A domain-pack framework skills should require the landed plan/orchestration substrate."),
		FrameworkState.bEverySkillRequiresPlanOrchestrationSubstrate
	);
	TestTrue(
		TEXT("S7-A domain-pack framework skills should require the landed provider usage/ops audit substrate."),
		FrameworkState.bEverySkillRequiresProviderUsageOperationsAuditSubstrate
	);
	TestTrue(
		TEXT("S7-A should preserve placeholder domain-pack deferral."),
		FrameworkState.bPlaceholderDomainPackDeferralRemainsPreserved
	);
	TestTrue(
		TEXT("S7-A should avoid retained domain-pack claims."),
		FrameworkState.bNoRetainedDomainPackClaims
	);
	TestTrue(
		TEXT("S7-A should avoid creative/media widening."),
		FrameworkState.bNoCreativeMediaWidening
	);

	const FHyperTwistSkillDomainPackFrameworkSkill* GroupingSkill =
		HyperTwistSkillPhaseS7ATestInternal::FindSkillById(
			FrameworkState,
			TEXT("skill/specify-domain-pack-grouping")
		);
	TestNotNull(
		TEXT("The specify-domain-pack-grouping skill should exist."),
		GroupingSkill
	);
	if (GroupingSkill != nullptr)
	{
		TestTrue(
			TEXT("The specify-domain-pack-grouping skill should declare enable/disable-grouping mode."),
			GroupingSkill->bSpecifiesEnableDisableGrouping
		);
		TestEqual(
			TEXT("The specify-domain-pack-grouping skill should depend on two landed plan/orchestration inputs."),
			GroupingSkill->RequiredPlanOrchestrationSkillCount,
			2
		);
		TestEqual(
			TEXT("The specify-domain-pack-grouping skill should depend on three landed provider usage/ops audit inputs."),
			GroupingSkill->RequiredProviderUsageAuditSkillCount,
			3
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS7ASerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS7A.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS7ASerializationRoundTripTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillDomainPackFrameworkState FrameworkState =
		UHyperTwistContractLibrary::MakeSampleSkillDomainPackFrameworkState();

	TestTrue(
		TEXT("The sample S7-A domain-pack framework state should be structurally valid before serialization."),
		FrameworkState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillDomainPackFrameworkStateToJson(
			FrameworkState
		);
	TestTrue(
		TEXT("Serialized S7-A JSON should include the retained-domain-pack guard field."),
		Json.Contains(TEXT("bNoRetainedDomainPackClaims"))
	);

	FHyperTwistSkillDomainPackFrameworkState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S7-A domain-pack framework JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillDomainPackFrameworkStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S7-A domain-pack framework state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S7-A skill count should match the original sample."),
		RoundTrippedState.SkillCount,
		FrameworkState.SkillCount
	);
	TestEqual(
		TEXT("Round-tripped S7-A enable/disable-grouping count should match the original sample."),
		RoundTrippedState.EnableDisableGroupingSkillCount,
		FrameworkState.EnableDisableGroupingSkillCount
	);

	return true;
}

#endif
