#pragma once

// Clean-room implementation for HyperTwist algorithm-language subsystem
// Implemented from governance docs only (Phase 0R-D, Phase 1R, Phase 5R-A)
// Source: Behavioral contracts from cubing/alg.js Model A handoff (GPL-3.0-or-later lane)
//         No source code inspection. Clean-room workflow only.
// Date: 2026-05-15
// Bound 2 — Traversal and transformation helpers

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "HyperTwistAlgorithm/HyperTwistAlgorithmTypes.h"
#include "HyperTwistAlgorithmTraversal.generated.h"

// ---------------------------------------------------------------------------
// UHyperTwistAlgorithmTraversal
//
// Stateless traversal and transformation operations on algorithm ASTs.
// All functions are pure (no side effects, no mutation of inputs).
//
// Bound 2 scope:
//   - InvertSequence     : structural inverse of an algorithm tree
//   - ExpandToFlatMoves  : flatten all structure to a BlockMove list
//   - CoalesceMoves      : combine adjacent same-move occurrences, cancel zeroes
//   - ExpandAndSimplify  : convenience composition of expand then coalesce
//
// Out of scope for this bound (deferred):
//   - Validation (Bound 3)
//   - JSON / URL / keyboard interchange (Bound 4)
//   - Integration with UHyperTwistMoveController or AWTscrambler
// ---------------------------------------------------------------------------

UCLASS()
class UNREALHYPERTWIST_API UHyperTwistAlgorithmTraversal : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	// -----------------------------------------------------------------------
	// InvertSequence
	//
	// Produce the structural inverse of an algorithm sequence.
	//
	// Semantics per node type:
	//   BlockMove   : negate Amount (1→-1, -1→1, 2→-2, 3→-3, …)
	//   Group       : reverse Inner node list and invert each; Amount unchanged
	//   Commutator  : [A, B]' = [B, A]  — swap A and B operands
	//   Conjugate   : [A: B]' = [A: B'] — invert B only; A (setup) is unchanged
	//   Pause / Newline / Comment : pass through unchanged
	//
	// The top-level node list of the sequence is reversed and each element
	// is individually inverted.
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static FHyperTwistAlgorithmSequence InvertSequence(
		const FHyperTwistAlgorithmSequence& Sequence
	);

	// -----------------------------------------------------------------------
	// ExpandToFlatSequence
	//
	// Recursively expand an algorithm sequence into a flat owned sequence.
	// Container nodes (Group, Commutator, Conjugate) are replaced by their
	// expanded unit sequences. Non-container units such as Pause, Newline,
	// and Comment are preserved in-order so the result can still flow through
	// the canonical serializer and structured JSON surfaces.
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static FHyperTwistAlgorithmSequence ExpandToFlatSequence(
		const FHyperTwistAlgorithmSequence& Sequence
	);

	// -----------------------------------------------------------------------
	// ExpandToFlatMoves
	//
	// Recursively expand an algorithm sequence into an ordered flat list of
	// FHyperTwistAlgorithmBlockMove values. All structural nodes (Group,
	// Commutator, Conjugate) are resolved; Pause, Newline, and Comment nodes
	// are omitted from the flat output.
	//
	// Expansion rules:
	//   BlockMove   : emitted as-is
	//   Group n     : inner expanded, then that expansion repeated n times
	//                 (negative n: expand inverted inner |n| times)
	//   Commutator  : [A, B] → A_flat + B_flat + A_flat_inverted + B_flat_inverted
	//   Conjugate   : [A: B] → A_flat + B_flat + A_flat_inverted
	//   Pause / Newline / Comment : skipped
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static TArray<FHyperTwistAlgorithmBlockMove> ExpandToFlatMoves(
		const FHyperTwistAlgorithmSequence& Sequence
	);

	// -----------------------------------------------------------------------
	// CoalesceMoves
	//
	// Accept a flat move list and return a simplified list where:
	//   - Adjacent moves with the same Family, MoveType, InnerLayer, and
	//     OuterLayer are combined by summing their Amount values.
	//   - Amounts are preserved as integer sums; no modulo-4 normalization
	//     is applied in this owner layer.
	//   - Moves with a resulting amount of 0 are removed (cancelled).
	//
	// The function makes a single left-to-right pass; it does not repeat
	// until a fixed point. Callers who need fully-simplified output on complex
	// algorithms may call it iteratively if needed (in practice one pass
	// suffices for the common cases).
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static TArray<FHyperTwistAlgorithmBlockMove> CoalesceMoves(
		const TArray<FHyperTwistAlgorithmBlockMove>& Moves
	);

	// -----------------------------------------------------------------------
	// CoalesceSequence
	//
	// Coalesce adjacent block moves across the owned AST while preserving the
	// surrounding unit stream. Non-move nodes remain in place and break
	// adjacency. Composite containers are preserved structurally, with their
	// child unit lists coalesced recursively.
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static FHyperTwistAlgorithmSequence CoalesceSequence(
		const FHyperTwistAlgorithmSequence& Sequence
	);

	// -----------------------------------------------------------------------
	// ExpandAndCoalesceSequence
	//
	// Convenience: ExpandToFlatSequence followed by CoalesceSequence.
	// Equivalent to:
	//   CoalesceSequence(ExpandToFlatSequence(Sequence))
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static FHyperTwistAlgorithmSequence ExpandAndCoalesceSequence(
		const FHyperTwistAlgorithmSequence& Sequence
	);

	// -----------------------------------------------------------------------
	// ExpandAndSimplify
	//
	// Convenience: ExpandToFlatMoves followed by CoalesceMoves.
	// Equivalent to:
	//   CoalesceMoves(ExpandToFlatMoves(Sequence))
	// -----------------------------------------------------------------------
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Algorithm|Traversal")
	static TArray<FHyperTwistAlgorithmBlockMove> ExpandAndSimplify(
		const FHyperTwistAlgorithmSequence& Sequence
	);
};
