#include "HyperTwistTraining/HyperTwistTrainingMagicCube5DLibrary.h"

namespace HyperTwistTrainingMagicCube5DLibraryInternal
{
	const TCHAR* MagicCube5DLicense = TEXT("MIT");

	FHyperTwistTrainingSourceAttribution MakeAttribution(
		const FString& TrackId,
		const FString& Notes
	)
	{
		FHyperTwistTrainingSourceAttribution Attribution;
		Attribution.SourceMode = EHyperTwistTrainingSourceMode::DirectDonor;
		Attribution.SourceRepo = TEXT("roice3/MagicCube5D");
		Attribution.SourceLicense = MagicCube5DLicense;
		Attribution.SourceTrackId = TrackId;
		Attribution.SourceNotes = Notes;
		return Attribution;
	}

	FHyperTwistTrainingMagicCube5DPackageReference MakePackageReference(
		const FString& PackageId,
		const FString& Label,
		const FString& ExportPath,
		const FString& OwnershipRole,
		const FString& LicensePosture,
		const FString& Summary,
		const TArray<FString>& RetainedSurfaceTags,
		const TArray<FString>& RequiredNoticeActions,
		const TArray<FString>& ExplicitExclusions,
		const FHyperTwistTrainingSourceAttribution& SourceAttribution
	)
	{
		FHyperTwistTrainingMagicCube5DPackageReference Reference;
		Reference.PackageId = PackageId;
		Reference.Label = Label;
		Reference.ExportPath = ExportPath;
		Reference.OwnershipRole = OwnershipRole;
		Reference.LicensePosture = LicensePosture;
		Reference.Summary = Summary;
		Reference.RetainedSurfaceTags = RetainedSurfaceTags;
		Reference.RequiredNoticeActions = RequiredNoticeActions;
		Reference.ExplicitExclusions = ExplicitExclusions;
		Reference.SourceAttribution = SourceAttribution;
		return Reference;
	}

	void AppendJoined(FString& OutText, const TArray<FString>& Values)
	{
		for (int32 Index = 0; Index < Values.Num(); ++Index)
		{
			if (Index > 0)
			{
				OutText.Append(TEXT(", "));
			}

			OutText.Append(Values[Index]);
		}
	}
}

FHyperTwistTrainingMagicCube5DReferenceBundle
UHyperTwistTrainingMagicCube5DLibrary::BuildBundledMagicCube5DReferenceBundle()
{
	using namespace HyperTwistTrainingMagicCube5DLibraryInternal;

	FHyperTwistTrainingMagicCube5DReferenceBundle Bundle;
	Bundle.ReferenceUtc = TEXT("2026-05-22T14:05:00Z");
	Bundle.PrimaryRuntimeProfileContractId = TEXT("magiccube5d-runtime-profile");
	Bundle.PrimaryPersistenceBoundaryId = TEXT("magiccube5d-persistence-boundary");
	Bundle.PrimaryViewProfileContractId = TEXT("magiccube5d-projection-view-profile");
	Bundle.PrimaryAttributionBoundaryId = TEXT("magiccube5d-mit-attribution-boundary");

	const TArray<FString> CommonNoticeActions =
	{
		TEXT("preserve the upstream MIT license text in third-party notices or equivalent release/legal materials"),
		TEXT("preserve the upstream copyright notice for Roice Nelson")
	};

	Bundle.PackageReferences =
	{
		MakePackageReference(
			TEXT("package/magiccube5d-family-core"),
			TEXT("MagicCube5D/workFiles/cube5D"),
			TEXT("./MagicCube5D/workFiles/cube5D.cpp"),
			TEXT("5d-runtime-profile-anchor"),
			TEXT("direct permissive donor"),
			TEXT("Order-parametric 5D cube-family runtime anchor for click-derived twists, fifth-axis view rotation, face visibility control, and family-specific projection defaults."),
			{
				TEXT("order-parametric 5D family sizing"),
				TEXT("click-derived twist derivation"),
				TEXT("control-click fifth-axis view rotation"),
				TEXT("face visibility toggles"),
				TEXT("projection-distance defaults")
			},
			CommonNoticeActions,
			{
				TEXT("Hyperspeedcube runtime-base replacement"),
				TEXT("generic non-Euclidean topology ownership"),
				TEXT("WinForms/OpenGL host-shell ownership")
			},
			MakeAttribution(
				TEXT("magiccube5d/family-core"),
				TEXT("Preserves the specialized MagicCube5D family runtime seam beneath the retained Hyperspeedcube runtime anchor without widening into a broad host-shell or renderer packet.")
			)
		),
		MakePackageReference(
			TEXT("package/magiccube5d-settings"),
			TEXT("MagicCube5D/workFiles/settings"),
			TEXT("./MagicCube5D/workFiles/settings.cpp"),
			TEXT("5d-runtime-default-support"),
			TEXT("direct permissive donor"),
			TEXT("Family defaults for puzzle order, accent emphasis, stereo mode, and face-visibility control for the bounded 5D runtime profile."),
			{
				TEXT("default order-three family mode"),
				TEXT("accent-emphasis defaults"),
				TEXT("stereo-mode default"),
				TEXT("face-visibility reset")
			},
			CommonNoticeActions,
			{
				TEXT("broad settings-platform ownership"),
				TEXT("UI settings-dialog ownership"),
				TEXT("generic rendering-profile ownership")
			},
			MakeAttribution(
				TEXT("magiccube5d/settings"),
				TEXT("Preserves bounded MagicCube5D family defaults without importing the legacy settings shell or stereo UI as product truth.")
			)
		),
		MakePackageReference(
			TEXT("package/magiccube5d-state-transformer"),
			TEXT("MagicCube5D/workFiles/stateTransformer"),
			TEXT("./MagicCube5D/workFiles/stateTransformer.cpp"),
			TEXT("5d-state-and-progress-support"),
			TEXT("direct permissive donor"),
			TEXT("Compact 5D state encoding, ten-face offset mapping, per-face sticker indexing, cubie-class solved-progress tracking, and color-signature cubie lookup for the bounded 5D family lane."),
			{
				TEXT("ten-face offset map"),
				TEXT("n^4 stickers-per-face indexing"),
				TEXT("sticker-array to state-matrix conversion"),
				TEXT("cubie-class solved counts"),
				TEXT("color-signature cubie lookup")
			},
			CommonNoticeActions,
			{
				TEXT("generic puzzle-state platform ownership"),
				TEXT("whole analytics ownership"),
				TEXT("generic non-Euclidean topology ownership")
			},
			MakeAttribution(
				TEXT("magiccube5d/state-transformer"),
				TEXT("Preserves the specialized MagicCube5D state/progress seam without treating it as the generic puzzle-state contract for all retained families.")
			)
		),
		MakePackageReference(
			TEXT("package/magiccube5d-loader"),
			TEXT("MagicCube5D/workFiles/loader"),
			TEXT("./MagicCube5D/workFiles/loader.cpp"),
			TEXT("5d-persistence-support"),
			TEXT("direct permissive donor"),
			TEXT("Family-specific MagicCube5D Version1 header, serialized ten-face state matrix, scrambled-flag persistence, compact twist-token save/load, and macro-sidecar persistence."),
			{
				TEXT("MagicCube5D Version1 header"),
				TEXT("ten-face state-matrix persistence"),
				TEXT("scrambled-flag persistence"),
				TEXT("compact twist-token save-load"),
				TEXT("MagicCube5D.macros sidecar")
			},
			CommonNoticeActions,
			{
				TEXT("first-party canonical replay ownership"),
				TEXT("host file-dialog ownership"),
				TEXT("generic notation ownership")
			},
			MakeAttribution(
				TEXT("magiccube5d/loader"),
				TEXT("Preserves the specialized MagicCube5D persistence seam without adopting the host-dialog shell or promoting the format to the generic product-wide replay contract.")
			)
		),
		MakePackageReference(
			TEXT("package/magiccube5d-twist"),
			TEXT("MagicCube5D/workFiles/twist"),
			TEXT("./MagicCube5D/workFiles/twist.h"),
			TEXT("5d-twist-ledger-support"),
			TEXT("direct permissive donor"),
			TEXT("Family-specific rotation-face sentinel, axis-pair encoding, slicemask flags, reverse-twist support, and macro twist arrays for the bounded 5D persistence lane."),
			{
				TEXT("rotation-face sentinel -1"),
				TEXT("axis-pair encoding"),
				TEXT("slicemask flags"),
				TEXT("reverse-twist support"),
				TEXT("macro twist arrays")
			},
			CommonNoticeActions,
			{
				TEXT("generic move-notation ownership"),
				TEXT("whole transformation-platform ownership"),
				TEXT("generic macro-platform ownership")
			},
			MakeAttribution(
				TEXT("magiccube5d/twist"),
				TEXT("Preserves the specialized MagicCube5D twist and macro token seam without promoting it into the generic notation or transformation contract for all retained families.")
			)
		)
	};

	FHyperTwistTrainingMagicCube5DRuntimeProfileContract RuntimeProfile;
	RuntimeProfile.ContractId = TEXT("magiccube5d-runtime-profile");
	RuntimeProfile.Title = TEXT("MagicCube5D family runtime profile");
	RuntimeProfile.Summary = TEXT("First-party HyperTwist contract for order-parametric 5D cube-family runtime semantics, fifth-axis interaction, and solved-progress telemetry beneath the retained Hyperspeedcube runtime anchor.");
	RuntimeProfile.RequiredPackageIds =
	{
		TEXT("package/magiccube5d-family-core"),
		TEXT("package/magiccube5d-settings"),
		TEXT("package/magiccube5d-state-transformer")
	};
	RuntimeProfile.OrderSurfaceTags =
	{
		TEXT("order-parametric n^5 family sizing"),
		TEXT("ten-face signed-axis family"),
		TEXT("n^4 stickers per face"),
		TEXT("face-offset and cubie-index mapping")
	};
	RuntimeProfile.InteractionSurfaceTags =
	{
		TEXT("click-derived two-sticker twist selection"),
		TEXT("control-click fifth-axis view rotation"),
		TEXT("explicit slicemask turn families"),
		TEXT("face visibility toggles")
	};
	RuntimeProfile.ProgressSurfaceTags =
	{
		TEXT("cubie-class solved counts"),
		TEXT("sticker-total solved progress"),
		TEXT("color-signature cubie highlighting"),
		TEXT("puzzle-order inference from loaded state")
	};
	RuntimeProfile.ExplicitExclusions =
	{
		TEXT("Hyperspeedcube runtime-base replacement"),
		TEXT("generic non-Euclidean topology ownership"),
		TEXT("WinForms/OpenGL host-shell ownership"),
		TEXT("broad renderer ownership")
	};
	RuntimeProfile.SourceAttribution = MakeAttribution(
		TEXT("magiccube5d/runtime-profile"),
		TEXT("Preserves the specialized MagicCube5D family runtime seam while keeping HyperTwist first-party for the broader runtime, notation, replay, and viewer shell.")
	);
	Bundle.RuntimeProfileContracts = {RuntimeProfile};

	FHyperTwistTrainingMagicCube5DPersistenceBoundary PersistenceBoundary;
	PersistenceBoundary.BoundaryId = TEXT("magiccube5d-persistence-boundary");
	PersistenceBoundary.Title = TEXT("MagicCube5D persistence, twist-history, and macro boundary");
	PersistenceBoundary.Summary = TEXT("First-party HyperTwist boundary for the specialized MagicCube5D file header, state serialization, compact twist-history, and macro-sidecar persistence seam.");
	PersistenceBoundary.RequiredPackageIds =
	{
		TEXT("package/magiccube5d-loader"),
		TEXT("package/magiccube5d-twist")
	};
	PersistenceBoundary.PersistenceSurfaceTags =
	{
		TEXT("MagicCube5D Version1 header"),
		TEXT("ten-face serialized state matrix"),
		TEXT("scrambled-flag persistence"),
		TEXT("puzzle-order inference from per-face sticker count"),
		TEXT("MagicCube5D.macros sidecar persistence")
	};
	PersistenceBoundary.TwistHistorySurfaceTags =
	{
		TEXT("rotation-face and axis-pair encoding"),
		TEXT("optional slicemask suffix"),
		TEXT("undo/redo twist ledger"),
		TEXT("view-rotation sentinel -1"),
		TEXT("reverse-twist replay")
	};
	PersistenceBoundary.MacroSurfaceTags =
	{
		TEXT("macro record lifecycle"),
		TEXT("macro rename and delete"),
		TEXT("forward macro execution"),
		TEXT("reverse macro execution")
	};
	PersistenceBoundary.ProvenanceCaveats =
	{
		TEXT("loaded puzzle order is inferred from per-face sticker count rather than an explicit persisted order field"),
		TEXT("save/load dialog filter text remains a legacy host-shell string and is not first-party product contract"),
		TEXT("compact twist tokens assume single-digit face and axis identifiers with an optional slicemask suffix"),
		TEXT("macro persistence stays in a separate MagicCube5D.macros sidecar rather than the main puzzle-state log")
	};
	PersistenceBoundary.ExplicitExclusions =
	{
		TEXT("first-party canonical replay or verification ownership"),
		TEXT("host file-dialog ownership"),
		TEXT("generic move-notation ownership"),
		TEXT("broad automation or tutorial macro ownership")
	};
	PersistenceBoundary.SourceAttribution = MakeAttribution(
		TEXT("magiccube5d/persistence-boundary"),
		TEXT("Preserves the specialized MagicCube5D persistence seam while keeping HyperTwist first-party for canonical replay, verification, and broader product-wide persistence contracts.")
	);
	Bundle.PersistenceBoundaries = {PersistenceBoundary};

	FHyperTwistTrainingMagicCube5DViewProfileContract ViewProfileContract;
	ViewProfileContract.ContractId = TEXT("magiccube5d-projection-view-profile");
	ViewProfileContract.Title = TEXT("MagicCube5D projection and focus view profile");
	ViewProfileContract.Summary = TEXT("First-party HyperTwist contract for MagicCube5D projection distances, stereo posture, face-visibility controls, and accent-driven focus posture above the dedicated 5D runtime profile without inheriting the legacy renderer or host shell.");
	ViewProfileContract.RequiredPackageIds =
	{
		TEXT("package/magiccube5d-family-core"),
		TEXT("package/magiccube5d-settings"),
		TEXT("package/magiccube5d-state-transformer")
	};
	ViewProfileContract.ProjectionSurfaceTags =
	{
		TEXT("5D projection distance"),
		TEXT("4D projection distance"),
		TEXT("face-offset spacing"),
		TEXT("sticker-offset spacing"),
		TEXT("sticker-size spacing")
	};
	ViewProfileContract.StereoSurfaceTags =
	{
		TEXT("stereo disabled default"),
		TEXT("cross-eyed stereo posture"),
		TEXT("anaglyph stereo posture"),
		TEXT("anaglyph no-color posture"),
		TEXT("stereo separation tuning")
	};
	ViewProfileContract.VisibilitySurfaceTags =
	{
		TEXT("all-faces visible default"),
		TEXT("per-face invisibility vector"),
		TEXT("show-all-cubie-stickers toggle"),
		TEXT("face-visibility reset"),
		TEXT("stereo blocks sticker picking")
	};
	ViewProfileContract.FocusSurfaceTags =
	{
		TEXT("accent emphasis ladder"),
		TEXT("control-click fifth-axis view rotation"),
		TEXT("color-signature cubie highlighting"),
		TEXT("order-three default family mode"),
		TEXT("view-centered solved-progress readout posture")
	};
	ViewProfileContract.ExplicitExclusions =
	{
		TEXT("WinForms/OpenGL host-shell ownership"),
		TEXT("stereo/anaglyph renderer ownership"),
		TEXT("generic hyper-runtime ownership"),
		TEXT("broad macro/tutorial shell widening")
	};
	ViewProfileContract.SourceAttribution = MakeAttribution(
		TEXT("magiccube5d/projection-view-profile"),
		TEXT("Preserves the MagicCube5D settings-derived projection and focus-view posture while keeping HyperTwist first-party for the actual host shell, stereo renderer behavior, and broader immersive runtime ownership.")
	);
	Bundle.ViewProfileContracts = {ViewProfileContract};

	FHyperTwistTrainingMagicCube5DAttributionBoundary AttributionBoundary;
	AttributionBoundary.BoundaryId = TEXT("magiccube5d-mit-attribution-boundary");
	AttributionBoundary.Title = TEXT("MagicCube5D donor attribution boundary");
	AttributionBoundary.Summary = TEXT("First-party HyperTwist compliance boundary for using MagicCube5D as a direct permissive donor for the bounded 5D family runtime-profile and persistence slice.");
	AttributionBoundary.AllowedUseTags =
	{
		TEXT("first-party reauthored subsystem implementation"),
		TEXT("direct permissive donor reference"),
		TEXT("bounded 5D runtime-profile and persistence contract use")
	};
	AttributionBoundary.RequiredNoticeActions = CommonNoticeActions;
	AttributionBoundary.ProvenanceCaveats =
	{
		TEXT("MagicCube5D is a specialized 5D family donor, not a generic hyper-runtime platform"),
		TEXT("Hyperspeedcube remains the primary runtime anchor for retained hyper puzzle ownership"),
		TEXT("MagicTile remains the generalized topology and non-Euclidean donor lane"),
		TEXT("the older local source zip remains provenance context only; the mirrored MIT repo is the canonical code-license source")
	};
	AttributionBoundary.ExplicitExclusions =
	{
		TEXT("silent attribution removal"),
		TEXT("pretending a broad host shell or renderer landed in this packet"),
		TEXT("treating generic topology ownership as incorporated"),
		TEXT("treating broad macro UX as fully incorporated")
	};
	AttributionBoundary.SourceAttribution = MakeAttribution(
		TEXT("magiccube5d/attribution-boundary"),
		TEXT("Records MIT attribution and packet bounds for MagicCube5D while keeping the first slice narrowly scoped to the dedicated 5D runtime-profile and persistence seam.")
	);
	Bundle.AttributionBoundaries = {AttributionBoundary};

	return Bundle;
}

bool UHyperTwistTrainingMagicCube5DLibrary::TryGetRuntimeProfileContractById(
	const FHyperTwistTrainingMagicCube5DReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingMagicCube5DRuntimeProfileContract& OutContract
)
{
	for (const FHyperTwistTrainingMagicCube5DRuntimeProfileContract& Contract : Bundle.RuntimeProfileContracts)
	{
		if (Contract.ContractId == ContractId)
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingMagicCube5DRuntimeProfileContract();
	return false;
}

bool UHyperTwistTrainingMagicCube5DLibrary::TryGetPersistenceBoundaryById(
	const FHyperTwistTrainingMagicCube5DReferenceBundle& Bundle,
	const FString& BoundaryId,
	FHyperTwistTrainingMagicCube5DPersistenceBoundary& OutBoundary
)
{
	for (const FHyperTwistTrainingMagicCube5DPersistenceBoundary& Boundary : Bundle.PersistenceBoundaries)
	{
		if (Boundary.BoundaryId == BoundaryId)
		{
			OutBoundary = Boundary;
			return true;
		}
	}

	OutBoundary = FHyperTwistTrainingMagicCube5DPersistenceBoundary();
	return false;
}

bool UHyperTwistTrainingMagicCube5DLibrary::TryGetAttributionBoundaryById(
	const FHyperTwistTrainingMagicCube5DReferenceBundle& Bundle,
	const FString& BoundaryId,
	FHyperTwistTrainingMagicCube5DAttributionBoundary& OutBoundary
)
{
	for (const FHyperTwistTrainingMagicCube5DAttributionBoundary& Boundary : Bundle.AttributionBoundaries)
	{
		if (Boundary.BoundaryId == BoundaryId)
		{
			OutBoundary = Boundary;
			return true;
		}
	}

	OutBoundary = FHyperTwistTrainingMagicCube5DAttributionBoundary();
	return false;
}

bool UHyperTwistTrainingMagicCube5DLibrary::TryGetViewProfileContractById(
	const FHyperTwistTrainingMagicCube5DReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingMagicCube5DViewProfileContract& OutContract
)
{
	for (const FHyperTwistTrainingMagicCube5DViewProfileContract& Contract : Bundle.ViewProfileContracts)
	{
		if (Contract.ContractId == ContractId)
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingMagicCube5DViewProfileContract();
	return false;
}

FString UHyperTwistTrainingMagicCube5DLibrary::BuildPackageChecklistTsv(
	const FHyperTwistTrainingMagicCube5DReferenceBundle& Bundle
)
{
	using namespace HyperTwistTrainingMagicCube5DLibraryInternal;

	FString Checklist = TEXT("PackageId\tLabel\tExportPath\tOwnershipRole\tLicensePosture\tRetainedSurfaceTags\tRequiredNoticeActions\tExplicitExclusions\n");
	for (const FHyperTwistTrainingMagicCube5DPackageReference& Reference : Bundle.PackageReferences)
	{
		FString RetainedSurfaceTags;
		AppendJoined(RetainedSurfaceTags, Reference.RetainedSurfaceTags);

		FString NoticeActions;
		AppendJoined(NoticeActions, Reference.RequiredNoticeActions);

		FString Exclusions;
		AppendJoined(Exclusions, Reference.ExplicitExclusions);

		Checklist += FString::Printf(
			TEXT("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n"),
			*Reference.PackageId,
			*Reference.Label,
			*Reference.ExportPath,
			*Reference.OwnershipRole,
			*Reference.LicensePosture,
			*RetainedSurfaceTags,
			*NoticeActions,
			*Exclusions
		);
	}

	return Checklist;
}
