#include "HyperTwistTraining/HyperTwistTrainingMagic120CellLibrary.h"

namespace HyperTwistTrainingMagic120CellLibraryInternal
{
	const TCHAR* Magic120CellLicense = TEXT("MIT");

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

	FHyperTwistTrainingMagic120CellPackageReference 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
	)
	{
		FHyperTwistTrainingMagic120CellPackageReference 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]);
		}
	}
}

FHyperTwistTrainingMagic120CellReferenceBundle
UHyperTwistTrainingMagic120CellLibrary::BuildBundledMagic120CellReferenceBundle()
{
	using namespace HyperTwistTrainingMagic120CellLibraryInternal;

	FHyperTwistTrainingMagic120CellReferenceBundle Bundle;
	Bundle.ReferenceUtc = TEXT("2026-05-22T09:15:00Z");
	Bundle.PrimaryRuntimeProfileContractId = TEXT("magic120cell-runtime-profile");
	Bundle.PrimaryPersistenceBoundaryId = TEXT("magic120cell-persistence-boundary");
	Bundle.PrimaryViewProfileContractId = TEXT("magic120cell-focus-view-profile");
	Bundle.PrimaryAttributionBoundaryId = TEXT("magic120cell-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/magic120cell-family-core"),
			TEXT("Magic120Cell/workFiles/magic120Cell"),
			TEXT("./Magic120Cell/workFiles/magic120Cell.cpp"),
			TEXT("120-cell-runtime-profile-anchor"),
			TEXT("direct permissive donor"),
			TEXT("Family-specific 120-cell organization, symmetry maps, hypercube overlay grouping, center-cell view control, and puzzle-type mode routing for the dedicated 4D megaminx analogue lane."),
			{
				TEXT("12-ring 120-cell organization"),
				TEXT("torus symmetry groups"),
				TEXT("hypercube symmetry groups"),
				TEXT("layer symmetry groups"),
				TEXT("ring symmetry groups"),
				TEXT("center-cell view recentering")
			},
			CommonNoticeActions,
			{
				TEXT("Hyperspeedcube runtime-base replacement"),
				TEXT("generic non-Euclidean topology ownership"),
				TEXT("WinForms/OpenGL host-shell ownership")
			},
			MakeAttribution(
				TEXT("magic120cell/family-core"),
				TEXT("Preserves the dedicated Magic120Cell family runtime profile beneath first-party HyperTwist runtime ownership without widening into a generic non-Euclidean shell.")
			)
		),
		MakePackageReference(
			TEXT("package/magic120cell-settings"),
			TEXT("Magic120Cell/workFiles/settings"),
			TEXT("./Magic120Cell/workFiles/settings.cpp"),
			TEXT("120-cell-mode-default-support"),
			TEXT("direct permissive donor"),
			TEXT("Family defaults for puzzle-type mode, symmetry mode, logical-visibility depth, center-cell selection, and physical visibility toggles."),
			{
				TEXT("full-color default"),
				TEXT("layer-display default"),
				TEXT("logical layer-depth default"),
				TEXT("center-cell default"),
				TEXT("group-visibility toggles")
			},
			CommonNoticeActions,
			{
				TEXT("broad settings-platform ownership"),
				TEXT("UI settings-dialog ownership"),
				TEXT("provider-profile ownership")
			},
			MakeAttribution(
				TEXT("magic120cell/settings"),
				TEXT("Preserves the bounded Magic120Cell runtime-mode defaults without importing the legacy settings UI shell.")
			)
		),
		MakePackageReference(
			TEXT("package/magic120cell-loader"),
			TEXT("Magic120Cell/workFiles/loader"),
			TEXT("./Magic120Cell/workFiles/loader.cpp"),
			TEXT("120-cell-persistence-support"),
			TEXT("direct permissive donor"),
			TEXT("Family-specific header, scrambled-state persistence, hex facelet serialization, and twist-history load/save support for the dedicated Magic120Cell lane."),
			{
				TEXT("Magic120Cell Version1 header"),
				TEXT("puzzle-type persistence"),
				TEXT("scrambled-flag persistence"),
				TEXT("hex facelet state serialization"),
				TEXT("full_scramble.log cache")
			},
			CommonNoticeActions,
			{
				TEXT("first-party canonical replay ownership"),
				TEXT("host file-dialog ownership"),
				TEXT("generic notation ownership")
			},
			MakeAttribution(
				TEXT("magic120cell/loader"),
				TEXT("Preserves the dedicated Magic120Cell persistence seam without adopting the host-dialog shell or promoting the format to a generic product-wide replay contract.")
			)
		),
		MakePackageReference(
			TEXT("package/magic120cell-twist"),
			TEXT("geometryLib/puzzle/twist"),
			TEXT("./geometryLib/puzzle/twist.h"),
			TEXT("120-cell-twist-ledger-support"),
			TEXT("direct permissive donor"),
			TEXT("Family-specific twist-hash and view-rotation support for Magic120Cell persistence and twist-history replay, including the explicit slicemask caveat."),
			{
				TEXT("twist-hash encoding"),
				TEXT("view-rotation flag"),
				TEXT("left-click direction flag"),
				TEXT("slicemask caveat")
			},
			CommonNoticeActions,
			{
				TEXT("generic move-notation ownership"),
				TEXT("whole transformation-platform ownership"),
				TEXT("generic puzzle-family twist ledger ownership")
			},
			MakeAttribution(
				TEXT("magic120cell/twist"),
				TEXT("Preserves the dedicated Magic120Cell twist-hash and view-rotation persistence seam without treating it as the generic transformation contract for all retained puzzle families.")
			)
		),
		MakePackageReference(
			TEXT("package/magic120cell-twist-history"),
			TEXT("geometryLib/puzzle/twistHistory"),
			TEXT("./geometryLib/puzzle/twistHistory.cpp"),
			TEXT("120-cell-history-undo-redo-support"),
			TEXT("direct permissive donor"),
			TEXT("Undo/redo and accumulated twist-ledger support for the dedicated Magic120Cell scramble and persistence lane."),
			{
				TEXT("undo ledger"),
				TEXT("redo ledger"),
				TEXT("twist accumulation"),
				TEXT("scramble-history persistence")
			},
			CommonNoticeActions,
			{
				TEXT("whole review-history ownership"),
				TEXT("first-party analytics ownership"),
				TEXT("generic persistence-platform ownership")
			},
			MakeAttribution(
				TEXT("magic120cell/twist-history"),
				TEXT("Preserves the dedicated Magic120Cell undo/redo and scramble-ledger seam without promoting it into the broader HyperTwist review or analytics stack.")
			)
		)
	};

	FHyperTwistTrainingMagic120CellRuntimeProfileContract RuntimeProfile;
	RuntimeProfile.ContractId = TEXT("magic120cell-runtime-profile");
	RuntimeProfile.Title = TEXT("Magic120Cell family runtime profile");
	RuntimeProfile.Summary = TEXT("First-party HyperTwist contract for dedicated 120-cell family puzzle-type modes, symmetry-scoped visibility groups, and center-cell view semantics beneath the Hyperspeedcube runtime anchor.");
	RuntimeProfile.RequiredPackageIds =
	{
		TEXT("package/magic120cell-family-core"),
		TEXT("package/magic120cell-settings")
	};
	RuntimeProfile.PuzzleTypeSurfaceTags =
	{
		TEXT("ring-color puzzle type"),
		TEXT("layer-color puzzle type"),
		TEXT("torus-color puzzle type"),
		TEXT("hypercube-color puzzle type"),
		TEXT("full-color puzzle type"),
		TEXT("antipodal-color puzzle type")
	};
	RuntimeProfile.SymmetrySurfaceTags =
	{
		TEXT("torus visibility groups"),
		TEXT("hypercube visibility groups"),
		TEXT("layer visibility groups"),
		TEXT("ring visibility groups"),
		TEXT("hypercube overlay points")
	};
	RuntimeProfile.VisibilitySurfaceTags =
	{
		TEXT("logical layer-depth visibility"),
		TEXT("physical group visibility toggles"),
		TEXT("center-cell recentering"),
		TEXT("view-rotation guard rails")
	};
	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("magic120cell/runtime-profile"),
		TEXT("Preserves the dedicated Magic120Cell runtime-profile lane while keeping HyperTwist first-party for the broader runtime, notation, replay, and viewer shell.")
	);
	Bundle.RuntimeProfileContracts = {RuntimeProfile};

	FHyperTwistTrainingMagic120CellPersistenceBoundary PersistenceBoundary;
	PersistenceBoundary.BoundaryId = TEXT("magic120cell-persistence-boundary");
	PersistenceBoundary.Title = TEXT("Magic120Cell persistence and twist-history boundary");
	PersistenceBoundary.Summary = TEXT("First-party HyperTwist boundary for the dedicated Magic120Cell file header, state serialization, scramble cache, and twist-history persistence seam.");
	PersistenceBoundary.RequiredPackageIds =
	{
		TEXT("package/magic120cell-loader"),
		TEXT("package/magic120cell-twist"),
		TEXT("package/magic120cell-twist-history")
	};
	PersistenceBoundary.PersistenceSurfaceTags =
	{
		TEXT("Magic120Cell Version1 header"),
		TEXT("puzzle-type persistence"),
		TEXT("scrambled-flag persistence"),
		TEXT("hex facelet state serialization"),
		TEXT("full_scramble.log cache")
	};
	PersistenceBoundary.TwistHistorySurfaceTags =
	{
		TEXT("twist-hash serialization"),
		TEXT("view-rotation and direction flags"),
		TEXT("undo/redo twist ledger"),
		TEXT("scramble-history replay")
	};
	PersistenceBoundary.ProvenanceCaveats =
	{
		TEXT("slice mask is not persisted in twist hash"),
		TEXT("save/load dialog filter text still says MagicCube5D log files"),
		TEXT("the full scramble shortcut assumes a sidecar full_scramble.log cache")
	};
	PersistenceBoundary.ExplicitExclusions =
	{
		TEXT("first-party canonical replay or verification ownership"),
		TEXT("host file-dialog ownership"),
		TEXT("generic puzzle-state persistence ownership"),
		TEXT("generic move-notation ownership")
	};
	PersistenceBoundary.SourceAttribution = MakeAttribution(
		TEXT("magic120cell/persistence-boundary"),
		TEXT("Preserves the dedicated Magic120Cell persistence seam while keeping HyperTwist first-party for canonical replay, verification, and broader product-wide persistence contracts.")
	);
	Bundle.PersistenceBoundaries = {PersistenceBoundary};

	FHyperTwistTrainingMagic120CellViewProfileContract ViewProfileContract;
	ViewProfileContract.ContractId = TEXT("magic120cell-focus-view-profile");
	ViewProfileContract.Title = TEXT("Magic120Cell symmetry-aware focus view profile");
	ViewProfileContract.Summary = TEXT("First-party HyperTwist contract for Magic120Cell projection, symmetry, visibility, and center-cell focus posture above the dedicated family runtime profile without inheriting the legacy host or renderer shell.");
	ViewProfileContract.RequiredPackageIds =
	{
		TEXT("package/magic120cell-family-core"),
		TEXT("package/magic120cell-settings")
	};
	ViewProfileContract.ProjectionSurfaceTags =
	{
		TEXT("4D projection distance"),
		TEXT("cell-distance spacing"),
		TEXT("cell-size spacing"),
		TEXT("sticker-size spacing"),
		TEXT("1C/2C/3C sticker ratio tuning")
	};
	ViewProfileContract.SymmetryPresetTags =
	{
		TEXT("full-puzzle default mode"),
		TEXT("layer-display default symmetry"),
		TEXT("torus focus preset"),
		TEXT("hypercube focus preset"),
		TEXT("ring focus preset")
	};
	ViewProfileContract.VisibilityPresetTags =
	{
		TEXT("logical visibility depth ladder"),
		TEXT("12-cell physical visibility vector"),
		TEXT("draw inverted cells toggle"),
		TEXT("reverse inverted-cell color toggle"),
		TEXT("wireframe remains non-authoritative")
	};
	ViewProfileContract.FocusSurfaceTags =
	{
		TEXT("center-cell recentering"),
		TEXT("1C highlight toggle"),
		TEXT("2C highlight toggle"),
		TEXT("3C highlight toggle"),
		TEXT("4C highlight toggle")
	};
	ViewProfileContract.ExplicitExclusions =
	{
		TEXT("WinForms/OpenGL host-shell ownership"),
		TEXT("broad renderer ownership"),
		TEXT("generic non-Euclidean topology ownership"),
		TEXT("broad interaction-shell widening")
	};
	ViewProfileContract.SourceAttribution = MakeAttribution(
		TEXT("magic120cell/focus-view-profile"),
		TEXT("Preserves the Magic120Cell settings-derived focus view posture while keeping HyperTwist first-party for the actual host shell, renderer, and broader immersive interaction runtime.")
	);
	Bundle.ViewProfileContracts = {ViewProfileContract};

	FHyperTwistTrainingMagic120CellAttributionBoundary AttributionBoundary;
	AttributionBoundary.BoundaryId = TEXT("magic120cell-mit-attribution-boundary");
	AttributionBoundary.Title = TEXT("Magic120Cell donor attribution boundary");
	AttributionBoundary.Summary = TEXT("First-party HyperTwist compliance boundary for using Magic120Cell as a direct permissive donor for the bounded family runtime-profile and persistence slice.");
	AttributionBoundary.AllowedUseTags =
	{
		TEXT("first-party reauthored subsystem implementation"),
		TEXT("direct permissive donor reference"),
		TEXT("bounded family runtime-profile and persistence contract use")
	};
	AttributionBoundary.RequiredNoticeActions = CommonNoticeActions;
	AttributionBoundary.ProvenanceCaveats =
	{
		TEXT("Magic120Cell is a dedicated 4D megaminx-analogue donor, not a generic topology platform"),
		TEXT("MagicTile remains the generalized tiling and topology donor lane"),
		TEXT("Hyperspeedcube remains the primary runtime anchor for retained hyper puzzle ownership")
	};
	AttributionBoundary.ExplicitExclusions =
	{
		TEXT("silent attribution removal"),
		TEXT("pretending a broad non-Euclidean shell landed in this packet"),
		TEXT("treating legacy host or renderer surfaces as incorporated")
	};
	AttributionBoundary.SourceAttribution = MakeAttribution(
		TEXT("magic120cell/attribution-boundary"),
		TEXT("Records MIT attribution and packet bounds for Magic120Cell while keeping the first slice narrowly scoped to the dedicated runtime-profile and persistence seam.")
	);
	Bundle.AttributionBoundaries = {AttributionBoundary};

	return Bundle;
}

bool UHyperTwistTrainingMagic120CellLibrary::TryGetRuntimeProfileContractById(
	const FHyperTwistTrainingMagic120CellReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingMagic120CellRuntimeProfileContract& OutContract
)
{
	for (const FHyperTwistTrainingMagic120CellRuntimeProfileContract& Contract : Bundle.RuntimeProfileContracts)
	{
		if (Contract.ContractId == ContractId)
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingMagic120CellRuntimeProfileContract();
	return false;
}

bool UHyperTwistTrainingMagic120CellLibrary::TryGetPersistenceBoundaryById(
	const FHyperTwistTrainingMagic120CellReferenceBundle& Bundle,
	const FString& BoundaryId,
	FHyperTwistTrainingMagic120CellPersistenceBoundary& OutBoundary
)
{
	for (const FHyperTwistTrainingMagic120CellPersistenceBoundary& Boundary : Bundle.PersistenceBoundaries)
	{
		if (Boundary.BoundaryId == BoundaryId)
		{
			OutBoundary = Boundary;
			return true;
		}
	}

	OutBoundary = FHyperTwistTrainingMagic120CellPersistenceBoundary();
	return false;
}

bool UHyperTwistTrainingMagic120CellLibrary::TryGetAttributionBoundaryById(
	const FHyperTwistTrainingMagic120CellReferenceBundle& Bundle,
	const FString& BoundaryId,
	FHyperTwistTrainingMagic120CellAttributionBoundary& OutBoundary
)
{
	for (const FHyperTwistTrainingMagic120CellAttributionBoundary& Boundary : Bundle.AttributionBoundaries)
	{
		if (Boundary.BoundaryId == BoundaryId)
		{
			OutBoundary = Boundary;
			return true;
		}
	}

	OutBoundary = FHyperTwistTrainingMagic120CellAttributionBoundary();
	return false;
}

bool UHyperTwistTrainingMagic120CellLibrary::TryGetViewProfileContractById(
	const FHyperTwistTrainingMagic120CellReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingMagic120CellViewProfileContract& OutContract
)
{
	for (const FHyperTwistTrainingMagic120CellViewProfileContract& Contract : Bundle.ViewProfileContracts)
	{
		if (Contract.ContractId == ContractId)
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingMagic120CellViewProfileContract();
	return false;
}

FString UHyperTwistTrainingMagic120CellLibrary::BuildPackageChecklistTsv(
	const FHyperTwistTrainingMagic120CellReferenceBundle& Bundle
)
{
	using namespace HyperTwistTrainingMagic120CellLibraryInternal;

	FString Checklist = TEXT("PackageId\tLabel\tExportPath\tOwnershipRole\tLicensePosture\tRetainedSurfaceTags\tRequiredNoticeActions\tExplicitExclusions\n");
	for (const FHyperTwistTrainingMagic120CellPackageReference& 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;
}
