// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS2CTestInternal
{
	const FHyperTwistSkillCleanRoomSkillSpec* FindSpecBySkillId(
		const FHyperTwistSkillCleanRoomSkillSpecState& SkillSpecState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillCleanRoomSkillSpec& Spec : SkillSpecState.Specs)
		{
			if (Spec.SkillId == SkillId)
			{
				return &Spec;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS2CSkillSpecCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS2C.SkillSpecCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS2CSkillSpecCoverageTest::RunTest(const FString& Parameters)
{
	const FHyperTwistSkillCleanRoomSkillSpecState SkillSpecState =
		UHyperTwistContractLibrary::MakeSampleSkillCleanRoomSkillSpecState();

	TestTrue(
		TEXT("The sample S2-C clean-room skill-spec state should be structurally valid."),
		SkillSpecState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S2-C should land one restrictive clean-room skill spec for the current skill family."),
		SkillSpecState.SkillCount,
		1
	);
	TestEqual(
		TEXT("S2-C should expose one clean-room skill spec."),
		SkillSpecState.SpecCount,
		1
	);
	TestEqual(
		TEXT("S2-C should expose three clean-room skill-spec steps."),
		SkillSpecState.StepCount,
		3
	);

	const FHyperTwistSkillCleanRoomSkillSpec* RouxSpec =
		HyperTwistSkillPhaseS2CTestInternal::FindSpecBySkillId(
			SkillSpecState,
			TEXT("skill/roux-session-review")
		);
	TestNotNull(
		TEXT("The Roux clean-room skill spec should exist."),
		RouxSpec
	);
	if (RouxSpec != nullptr)
	{
		TestEqual(
			TEXT("The Roux clean-room skill spec should bind to the bounded training review artifact."),
			RouxSpec->OutputArtifactKinds[0],
			FString(TEXT("artifact/training-review-brief"))
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS2CFirstPartyTermsOnlyTest,
	"HyperTwist.FirstParty.Skill.PhaseS2C.FirstPartyTermsOnly",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS2CFirstPartyTermsOnlyTest::RunTest(const FString& Parameters)
{
	const FHyperTwistSkillCleanRoomSkillSpecState SkillSpecState =
		UHyperTwistContractLibrary::MakeSampleSkillCleanRoomSkillSpecState();

	TestTrue(
		TEXT("The sample S2-C clean-room skill-spec state should be structurally valid."),
		SkillSpecState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("Every S2-C skill spec should use first-party terms only."),
		SkillSpecState.bEverySpecUsesFirstPartyTerms
	);
	TestTrue(
		TEXT("Every S2-C skill spec should avoid donor wording."),
		SkillSpecState.bEverySpecAvoidsDonorWording
	);
	TestTrue(
		TEXT("Every S2-C skill spec should bind to the landed command-contract state."),
		SkillSpecState.bEverySpecBindsToCommandContractState
	);
	TestTrue(
		TEXT("Every S2-C skill spec should be ready for future implementation while remaining non-live now."),
		SkillSpecState.bEverySpecReadyForFutureImplementation
	);
	TestTrue(
		TEXT("No S2-C skill spec should claim live implementation."),
		SkillSpecState.bNoSpecClaimsLiveImplementation
	);
	TestTrue(
		TEXT("Every S2-C skill spec should use declaration-only validation."),
		SkillSpecState.bEverySpecUsesDeclarationOnlyValidation
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS2CSerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS2C.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS2CSerializationRoundTripTest::RunTest(const FString& Parameters)
{
	const FHyperTwistSkillCleanRoomSkillSpecState SkillSpecState =
		UHyperTwistContractLibrary::MakeSampleSkillCleanRoomSkillSpecState();

	TestTrue(
		TEXT("The sample S2-C clean-room skill-spec state should be structurally valid before serialization."),
		SkillSpecState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillCleanRoomSkillSpecStateToJson(SkillSpecState);
	TestTrue(
		TEXT("Serialized S2-C JSON should include the future-implementation readiness guard field."),
		Json.Contains(TEXT("bEverySpecReadyForFutureImplementation"))
	);

	FHyperTwistSkillCleanRoomSkillSpecState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S2-C clean-room skill-spec JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillCleanRoomSkillSpecStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S2-C clean-room skill-spec state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S2-C spec count should match the original sample."),
		RoundTrippedState.SpecCount,
		SkillSpecState.SpecCount
	);
	TestEqual(
		TEXT("Round-tripped S2-C step count should match the original sample."),
		RoundTrippedState.StepCount,
		SkillSpecState.StepCount
	);

	return true;
}

#endif
