// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS6ATestInternal
{
	const FHyperTwistSkillProviderProfileRoutingSkill* FindSkillById(
		const FHyperTwistSkillProviderProfileRoutingState& ProviderProfileRoutingState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillProviderProfileRoutingSkill& Skill :
			ProviderProfileRoutingState.Skills)
		{
			if (Skill.SkillId == SkillId)
			{
				return &Skill;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS6AProviderProfileRoutingCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS6A.ProviderProfileRoutingCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS6AProviderProfileRoutingCoverageTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillProviderProfileRoutingState ProviderProfileRoutingState =
		UHyperTwistContractLibrary::MakeSampleSkillProviderProfileRoutingState();

	TestTrue(
		TEXT("The sample S6-A provider-profile/routing state should be structurally valid."),
		ProviderProfileRoutingState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S6-A should expose three bounded provider-profile/routing skills."),
		ProviderProfileRoutingState.SkillCount,
		3
	);
	TestEqual(
		TEXT("S6-A should expose one provider-profile inspection skill."),
		ProviderProfileRoutingState.ProviderProfileInspectionSkillCount,
		1
	);
	TestEqual(
		TEXT("S6-A should expose one BYOK-profile setup skill."),
		ProviderProfileRoutingState.ByokProfileSetupSkillCount,
		1
	);
	TestEqual(
		TEXT("S6-A should expose one provider-routing diagnostic skill."),
		ProviderProfileRoutingState.RoutingDiagnosticSkillCount,
		1
	);

	const FHyperTwistSkillProviderProfileRoutingSkill* InspectSkill =
		HyperTwistSkillPhaseS6ATestInternal::FindSkillById(
			ProviderProfileRoutingState,
			TEXT("skill/inspect-provider-profile")
		);
	TestNotNull(
		TEXT("The inspect-provider-profile skill should exist."),
		InspectSkill
	);
	if (InspectSkill != nullptr)
	{
		TestEqual(
			TEXT("The inspect-provider-profile skill should bind to the first-party provider-profile inspection service."),
			InspectSkill->ServiceBindingId,
			FString(TEXT("service/skills/inspect-provider-profile"))
		);
		TestTrue(
			TEXT("The inspect-provider-profile skill should declare provider-profile inspection mode."),
			InspectSkill->bInspectsProviderProfile
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS6ACustomEndpointAcceptanceGateTest,
	"HyperTwist.FirstParty.Skill.PhaseS6A.CustomEndpointAcceptanceGate",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS6ACustomEndpointAcceptanceGateTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillProviderProfileRoutingState ProviderProfileRoutingState =
		UHyperTwistContractLibrary::MakeSampleSkillProviderProfileRoutingState();

	TestTrue(
		TEXT("The sample S6-A provider-profile/routing state should be structurally valid."),
		ProviderProfileRoutingState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("S6-A should keep OpenAI-compatible custom endpoints first-class."),
		ProviderProfileRoutingState.bOpenAiCompatibleCustomEndpointsRemainFirstClass
	);
	TestTrue(
		TEXT("S6-A should preserve user-labeled BYOK profile support."),
		ProviderProfileRoutingState.bUserLabeledByokProfilesRemainSupported
	);
	TestTrue(
		TEXT("S6-A should preserve provider neutrality."),
		ProviderProfileRoutingState.bProviderNeutralityRemainsPreserved
	);
	TestTrue(
		TEXT("S6-A should avoid provider-specific overlay widening."),
		ProviderProfileRoutingState.bNoProviderSpecificOverlayWidening
	);

	const FHyperTwistSkillProviderProfileRoutingSkill* DiagnoseSkill =
		HyperTwistSkillPhaseS6ATestInternal::FindSkillById(
			ProviderProfileRoutingState,
			TEXT("skill/diagnose-provider-routing")
		);
	TestNotNull(
		TEXT("The diagnose-provider-routing skill should exist."),
		DiagnoseSkill
	);
	if (DiagnoseSkill != nullptr)
	{
		TestEqual(
			TEXT("The diagnose-provider-routing skill should depend on the landed provider wrapper."),
			DiagnoseSkill->RequiredAnalyzerWrapperSkillCount,
			1
		);
		TestTrue(
			TEXT("The diagnose-provider-routing skill should declare routing-diagnostic mode."),
			DiagnoseSkill->bDiagnosesRouting
		);
		TestTrue(
			TEXT("The diagnose-provider-routing skill should preserve the custom-endpoint acceptance gate."),
			DiagnoseSkill->bPreservesOpenAiCompatibleCustomEndpointFirstClass
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS6ASerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS6A.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS6ASerializationRoundTripTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillProviderProfileRoutingState ProviderProfileRoutingState =
		UHyperTwistContractLibrary::MakeSampleSkillProviderProfileRoutingState();

	TestTrue(
		TEXT("The sample S6-A provider-profile/routing state should be structurally valid before serialization."),
		ProviderProfileRoutingState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillProviderProfileRoutingStateToJson(
			ProviderProfileRoutingState
		);
	TestTrue(
		TEXT("Serialized S6-A JSON should include the custom-endpoint acceptance field."),
		Json.Contains(TEXT("bOpenAiCompatibleCustomEndpointsRemainFirstClass"))
	);

	FHyperTwistSkillProviderProfileRoutingState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S6-A provider-profile/routing JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillProviderProfileRoutingStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S6-A provider-profile/routing state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S6-A skill count should match the original sample."),
		RoundTrippedState.SkillCount,
		ProviderProfileRoutingState.SkillCount
	);
	TestEqual(
		TEXT("Round-tripped S6-A routing-diagnostic count should match the original sample."),
		RoundTrippedState.RoutingDiagnosticSkillCount,
		ProviderProfileRoutingState.RoutingDiagnosticSkillCount
	);

	return true;
}

#endif
