// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"

#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistSkillPhaseS5ATestInternal
{
	const FHyperTwistSkillWorkflowReviewSkill* FindSkillById(
		const FHyperTwistSkillWorkflowReviewState& WorkflowReviewState,
		const FString& SkillId
	)
	{
		for (const FHyperTwistSkillWorkflowReviewSkill& Skill :
			WorkflowReviewState.Skills)
		{
			if (Skill.SkillId == SkillId)
			{
				return &Skill;
			}
		}

		return nullptr;
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS5AWorkflowReviewCoverageTest,
	"HyperTwist.FirstParty.Skill.PhaseS5A.WorkflowReviewCoverage",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS5AWorkflowReviewCoverageTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillWorkflowReviewState WorkflowReviewState =
		UHyperTwistContractLibrary::MakeSampleSkillWorkflowReviewState();

	TestTrue(
		TEXT("The sample S5-A workflow-review state should be structurally valid."),
		WorkflowReviewState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("S5-A should expose three workflow/review skills."),
		WorkflowReviewState.SkillCount,
		3
	);
	TestEqual(
		TEXT("S5-A should expose three live workflow/review skills."),
		WorkflowReviewState.LiveSkillCount,
		3
	);
	TestEqual(
		TEXT("S5-A should expose one proposal-review skill."),
		WorkflowReviewState.ProposalReviewSkillCount,
		1
	);
	TestEqual(
		TEXT("S5-A should expose one diff-review skill."),
		WorkflowReviewState.DiffReviewSkillCount,
		1
	);
	TestEqual(
		TEXT("S5-A should expose one bounded workflow-wrapper skill."),
		WorkflowReviewState.BoundedWorkflowWrapperSkillCount,
		1
	);

	const FHyperTwistSkillWorkflowReviewSkill* ProposalReviewSkill =
		HyperTwistSkillPhaseS5ATestInternal::FindSkillById(
			WorkflowReviewState,
			TEXT("skill/review-proposal")
		);
	TestNotNull(
		TEXT("The review-proposal skill should exist."),
		ProposalReviewSkill
	);
	if (ProposalReviewSkill != nullptr)
	{
		TestEqual(
			TEXT("The review-proposal skill should bind to the bounded proposal-review artifact."),
			ProposalReviewSkill->OutputArtifactKinds[0],
			FString(TEXT("artifact/proposal-review-brief"))
		);
		TestTrue(
			TEXT("The review-proposal skill should declare proposal-review mode."),
			ProposalReviewSkill->bReviewsProposal
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS5ABoundedWorkflowReviewTest,
	"HyperTwist.FirstParty.Skill.PhaseS5A.BoundedWorkflowReview",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS5ABoundedWorkflowReviewTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillWorkflowReviewState WorkflowReviewState =
		UHyperTwistContractLibrary::MakeSampleSkillWorkflowReviewState();

	TestTrue(
		TEXT("The sample S5-A workflow-review state should be structurally valid."),
		WorkflowReviewState.IsStructurallyValid()
	);
	TestTrue(
		TEXT("Every live S5-A skill should read authoritative workflow and review surfaces."),
		WorkflowReviewState.bEveryLiveSkillReadsAuthoritativeWorkflowAndReviewSurfaces
	);
	TestTrue(
		TEXT("Every live S5-A skill should keep validation-harness coverage."),
		WorkflowReviewState.bEveryLiveSkillHasValidationHarnessCoverage
	);
	TestTrue(
		TEXT("S5-A workflow/review wrappers should remain structurally bounded."),
		WorkflowReviewState.bWorkflowReviewRemainsBounded
	);
	TestTrue(
		TEXT("S5-A workflow/review wrappers should require the landed extraction substrate."),
		WorkflowReviewState.bEverySkillRequiresExtractionSubstrate
	);
	TestTrue(
		TEXT("S5-A workflow/review wrappers should require the landed workflow-memory substrate."),
		WorkflowReviewState.bEverySkillRequiresWorkflowMemorySubstrate
	);
	TestTrue(
		TEXT("S5-A workflow/review wrappers should require the landed design-shell substrate."),
		WorkflowReviewState.bEverySkillRequiresDesignShellSubstrate
	);
	TestTrue(
		TEXT("S5-A should avoid implementation-review and delegation widening."),
		WorkflowReviewState.bNoImplementationReviewDelegationWidening
	);
	TestTrue(
		TEXT("S5-A should avoid plan-synthesis widening."),
		WorkflowReviewState.bNoPlanSynthesisWidening
	);

	const FHyperTwistSkillWorkflowReviewSkill* WorkflowWrapperSkill =
		HyperTwistSkillPhaseS5ATestInternal::FindSkillById(
			WorkflowReviewState,
			TEXT("skill/wrap-bounded-workflow")
		);
	TestNotNull(
		TEXT("The wrap-bounded-workflow skill should exist."),
		WorkflowWrapperSkill
	);
	if (WorkflowWrapperSkill != nullptr)
	{
		TestTrue(
			TEXT("The wrap-bounded-workflow skill should declare bounded workflow-wrapper mode."),
			WorkflowWrapperSkill->bWrapsBoundedWorkflow
		);
		TestTrue(
			TEXT("The wrap-bounded-workflow skill should depend on the workflow-memory substrate."),
			WorkflowWrapperSkill->bRequiresWorkflowMemorySubstrate
		);
		TestTrue(
			TEXT("The wrap-bounded-workflow skill should explicitly avoid plan-synthesis widening."),
			WorkflowWrapperSkill->bAvoidsPlanSynthesisWidening
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistSkillPhaseS5ASerializationRoundTripTest,
	"HyperTwist.FirstParty.Skill.PhaseS5A.SerializationRoundTrip",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistSkillPhaseS5ASerializationRoundTripTest::RunTest(
	const FString& Parameters
)
{
	const FHyperTwistSkillWorkflowReviewState WorkflowReviewState =
		UHyperTwistContractLibrary::MakeSampleSkillWorkflowReviewState();

	TestTrue(
		TEXT("The sample S5-A workflow-review state should be structurally valid before serialization."),
		WorkflowReviewState.IsStructurallyValid()
	);

	const FString Json =
		UHyperTwistContractLibrary::SerializeSkillWorkflowReviewStateToJson(
			WorkflowReviewState
		);
	TestTrue(
		TEXT("Serialized S5-A JSON should include the plan-synthesis guard field."),
		Json.Contains(TEXT("bNoPlanSynthesisWidening"))
	);

	FHyperTwistSkillWorkflowReviewState RoundTrippedState;
	TestTrue(
		TEXT("Deserializing the S5-A workflow-review JSON should succeed."),
		UHyperTwistContractLibrary::DeserializeSkillWorkflowReviewStateFromJson(
			Json,
			RoundTrippedState
		)
	);
	TestTrue(
		TEXT("Round-tripped S5-A workflow-review state should remain structurally valid."),
		RoundTrippedState.IsStructurallyValid()
	);
	TestEqual(
		TEXT("Round-tripped S5-A skill count should match the original sample."),
		RoundTrippedState.SkillCount,
		WorkflowReviewState.SkillCount
	);
	TestEqual(
		TEXT("Round-tripped S5-A live-skill count should match the original sample."),
		RoundTrippedState.LiveSkillCount,
		WorkflowReviewState.LiveSkillCount
	);

	return true;
}

#endif
