// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS4CTestInternal
{
	const FHyperTwistSkillDesignShellSkill* FindSkillById(
		const FHyperTwistSkillDesignShellState& DesignShellState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillDesignShellSkill& Skill : DesignShellState.Skills)
		{
			if (Skill.SkillId == SkillId)
			{
				return &Skill;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS4CDesignShellCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS4C.DesignShellCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS4CDesignShellCoverageTest::RunTest(const FString& Parameters)
{
	const FHyperTwistSkillDesignShellState DesignShellState =
		UHyperTwistContractLibrary::MakeSampleSkillDesignShellState();

	TestTrue(
		TEXT("The sample S4-C design-shell state should be structurally valid."),
		DesignShellState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S4-C should expose two design-shell skills."),
		DesignShellState.SkillCount,
		2
	);
	TestEqual(
		TEXT("S4-C should expose two live design-shell skills."),
		DesignShellState.LiveSkillCount,
		2
	);
	TestEqual(
		TEXT("S4-C should expose one design-shell translation skill."),
		DesignShellState.DesignShellTranslationSkillCount,
		1
	);
	TestEqual(
		TEXT("S4-C should expose one interaction-contract translation skill."),
		DesignShellState.InteractionContractTranslationSkillCount,
		1
	);

	const FHyperTwistSkillDesignShellSkill* DesignShellSkill =
		HyperTwistSkillPhaseS4CTestInternal::FindSkillById(
			DesignShellState,
			TEXT("skill/translate-design-shell")
		);
	TestNotNull(
		TEXT("The translate-design-shell skill should exist."),
		DesignShellSkill
	);
	if (DesignShellSkill != nullptr)
	{
		TestEqual(
			TEXT("The translate-design-shell skill should bind to the bounded native design-shell artifact."),
			DesignShellSkill->OutputArtifactKinds[0],
			FString(TEXT("artifact/native-design-shell-translation-brief"))
		);
		TestTrue(
			TEXT("The translate-design-shell skill should declare design-shell translation."),
			DesignShellSkill->bTranslatesDesignShell
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS4CBoundedDesignShellTranslationTest,
	"HyperTwist.FirstParty.Skill.PhaseS4C.BoundedDesignShellTranslation",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS4CBoundedDesignShellTranslationTest::RunTest(const FString& Parameters)
{
	const FHyperTwistSkillDesignShellState DesignShellState =
		UHyperTwistContractLibrary::MakeSampleSkillDesignShellState();

	TestTrue(
		TEXT("The sample S4-C design-shell state should be structurally valid."),
		DesignShellState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("Every live S4-C skill should read authoritative docs, browser, and design surfaces."),
		DesignShellState.bEveryLiveSkillReadsAuthoritativeDocsBrowserAndDesignSurfaces
	);
	TestTrue(
		TEXT("Every live S4-C skill should keep validation-harness coverage."),
		DesignShellState.bEveryLiveSkillHasValidationHarnessCoverage
	);
	TestTrue(
		TEXT("S4-C design-shell translation should remain structurally bounded."),
		DesignShellState.bDesignShellTranslationRemainsBounded
	);
	TestTrue(
		TEXT("S4-C design-shell translation should require the landed extraction substrate."),
		DesignShellState.bEverySkillRequiresExtractionSubstrate
	);
	TestTrue(
		TEXT("S4-C design-shell translation should require the landed browser diagnostics substrate."),
		DesignShellState.bEverySkillRequiresBrowserDiagnosticsSubstrate
	);
	TestTrue(
		TEXT("S4-C design-shell translation should avoid generic browser-shell widening."),
		DesignShellState.bNoGenericBrowserShellWidening
	);

	const FHyperTwistSkillDesignShellSkill* InteractionSkill =
		HyperTwistSkillPhaseS4CTestInternal::FindSkillById(
			DesignShellState,
			TEXT("skill/translate-design-interaction")
		);
	TestNotNull(
		TEXT("The translate-design-interaction skill should exist."),
		InteractionSkill
	);
	if (InteractionSkill != nullptr)
	{
		TestTrue(
			TEXT("The translate-design-interaction skill should declare interaction-contract translation."),
			InteractionSkill->bTranslatesInteractionContract
		);
		TestTrue(
			TEXT("The translate-design-interaction skill should depend on the browser diagnostics substrate."),
			InteractionSkill->bRequiresBrowserDiagnosticsSubstrate
		);
		TestTrue(
			TEXT("The translate-design-interaction skill should explicitly avoid generic browser-shell widening."),
			InteractionSkill->bAvoidsGenericBrowserShellWidening
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS4CSerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS4C.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS4CSerializationRoundTripTest::RunTest(const FString& Parameters)
{
	const FHyperTwistSkillDesignShellState DesignShellState =
		UHyperTwistContractLibrary::MakeSampleSkillDesignShellState();

	TestTrue(
		TEXT("The sample S4-C design-shell state should be structurally valid before serialization."),
		DesignShellState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillDesignShellStateToJson(
			DesignShellState
		);
	TestTrue(
		TEXT("Serialized S4-C JSON should include the browser-diagnostics-substrate guard field."),
		Json.Contains(TEXT("bEverySkillRequiresBrowserDiagnosticsSubstrate"))
	);

	FHyperTwistSkillDesignShellState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S4-C design-shell JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillDesignShellStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S4-C design-shell state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S4-C skill count should match the original sample."),
		RoundTrippedState.SkillCount,
		DesignShellState.SkillCount
	);
	TestEqual(
		TEXT("Round-tripped S4-C live-skill count should match the original sample."),
		RoundTrippedState.LiveSkillCount,
		DesignShellState.LiveSkillCount
	);

	return true;
}

#endif
