#include "HyperTwistTraining/HyperTwistTrainingMediaExportLibrary.h"

namespace HyperTwistTrainingMediaExportLibraryInternal
{
	const TCHAR* MediaExportRepo = TEXT("remotion-dev/remotion");
	const TCHAR* MediaExportLicense = TEXT("Remotion custom two-tier license; @remotion/studio is MIT but player, renderer, and media-parser remain under the checked Remotion license posture");

	FHyperTwistTrainingSourceAttribution MakeAttribution(
		const FString& TrackId,
		const FString& Notes
	)
	{
		FHyperTwistTrainingSourceAttribution Attribution;
		Attribution.SourceMode = EHyperTwistTrainingSourceMode::DirectDonor;
		Attribution.SourceRepo = MediaExportRepo;
		Attribution.SourceLicense = MediaExportLicense;
		Attribution.SourceTrackId = TrackId;
		Attribution.SourceNotes = Notes;
		return Attribution;
	}

	FHyperTwistTrainingMediaExportPackageReference MakePackageReference(
		const FString& PackageId,
		const FString& Label,
		const FString& PackagePath,
		const FString& UsagePosture,
		const FString& LicensePosture,
		const FString& Summary,
		const TArray<FString>& ApprovedWorkflowTags,
		const TArray<FString>& ExplicitExclusions,
		const FHyperTwistTrainingSourceAttribution& SourceAttribution
	)
	{
		FHyperTwistTrainingMediaExportPackageReference Reference;
		Reference.PackageId = PackageId;
		Reference.Label = Label;
		Reference.PackagePath = PackagePath;
		Reference.UsagePosture = UsagePosture;
		Reference.LicensePosture = LicensePosture;
		Reference.Summary = Summary;
		Reference.ApprovedWorkflowTags = ApprovedWorkflowTags;
		Reference.ExplicitExclusions = ExplicitExclusions;
		Reference.SourceAttribution = SourceAttribution;
		return Reference;
	}
}

FHyperTwistTrainingMediaExportReferenceBundle
UHyperTwistTrainingMediaExportLibrary::BuildBundledMediaExportReferenceBundle()
{
	using namespace HyperTwistTrainingMediaExportLibraryInternal;

	FHyperTwistTrainingMediaExportReferenceBundle Bundle;
	Bundle.ReferenceUtc = TEXT("2026-05-13T23:59:00Z");
	Bundle.PrimaryEmbeddedPlaybackContractId = TEXT("remotion-embedded-playback-and-controls");
	Bundle.PrimaryRenderOrchestrationContractId = TEXT("remotion-render-orchestration-and-export");
	Bundle.PrimaryMediaParserContractId = TEXT("remotion-media-parser-and-worker-seeking");
	Bundle.PrimaryExplainerStudioContractId = TEXT("remotion-explainer-studio-preview-and-output-registration");
	Bundle.PrimaryComplianceBoundaryId = TEXT("remotion-commercial-sidecar-and-package-split-boundary");

	Bundle.PackageReferences =
	{
		MakePackageReference(
			TEXT("package/remotion-root"),
			TEXT("Remotion monorepo boundary"),
			TEXT("./"),
			TEXT("bounded-media-export-reference"),
			TEXT("Custom two-tier commercial license with free-use eligibility limited by entity type and size"),
			TEXT("Root boundary reference for generated coaching media, replay explainers, embeddable playback, and parser or renderer seams while keeping the broader authoring shell, templates, and hosted deployment stack outside HyperTwist ownership."),
			{TEXT("media-export-boundary"), TEXT("source-routing"), TEXT("commercial-license-review")},
			{
				TEXT("whole authoring product shell adoption"),
				TEXT("template and marketing shell inheritance"),
				TEXT("cloud render or hosted deployment platform ownership")
			},
			MakeAttribution(
				TEXT("media-export/package-root"),
				TEXT("Preserves the commercial-license boundary, package split, and bounded-sidecar posture so HyperTwist can land first-party export and explainer contracts without treating the monorepo as a carefree donor.")
			)
		),
		MakePackageReference(
			TEXT("package/remotion-player"),
			TEXT("Embedded player surfaces"),
			TEXT("./packages/player"),
			TEXT("bounded-embedded-playback-reference"),
			TEXT("SEE LICENSE IN LICENSE.md"),
			TEXT("Embeddable timeline-aware playback surface with explicit duration, fps, composition dimensions, control toggles, poster behaviors, playback-rate handling, and imperative player methods for first-party HyperTwist replay explainers."),
			{TEXT("embedded-playback"), TEXT("replay-explainer"), TEXT("timeline-controls")},
			{
				TEXT("whole React player shell inheritance"),
				TEXT("direct donor API-name preservation")
			},
			MakeAttribution(
				TEXT("media-export/player"),
				TEXT("Preserves the bounded embedded-player, timeline-control, and poster or buffering seams from the retained Remotion player lane.")
			)
		),
		MakePackageReference(
			TEXT("package/remotion-renderer"),
			TEXT("Render and export orchestration surfaces"),
			TEXT("./packages/renderer"),
			TEXT("bounded-render-orchestration-reference"),
			TEXT("SEE LICENSE IN LICENSE.md"),
			TEXT("Codec-aware export orchestration, progress callbacks, cancellation, output validation, and browser-backed render pipeline seams for first-party HyperTwist coaching-video and replay recap export workflows."),
			{TEXT("media-export"), TEXT("render-orchestration"), TEXT("progress-reporting")},
			{
				TEXT("whole Node or Bun render-service shell"),
				TEXT("direct donor CLI or deployment inheritance")
			},
			MakeAttribution(
				TEXT("media-export/renderer"),
				TEXT("Preserves the retained renderer-side export, validation, and progress or cancellation seams from Remotion for bounded HyperTwist media-export use.")
			)
		),
		MakePackageReference(
			TEXT("package/remotion-media-parser"),
			TEXT("Media parser and worker surfaces"),
			TEXT("./packages/media-parser"),
			TEXT("bounded-media-parser-reference"),
			TEXT("Remotion License https://remotion.dev/license"),
			TEXT("Worker-aware media parsing, track callbacks, metadata extraction, and seeking-hint seams for first-party HyperTwist replay inspection, recap assembly, and export preflight workflows."),
			{TEXT("media-parser"), TEXT("track-inspection"), TEXT("worker-seeking")},
			{
				TEXT("whole generic media processing platform ownership"),
				TEXT("direct donor parser API preservation")
			},
			MakeAttribution(
				TEXT("media-export/media-parser"),
				TEXT("Preserves the retained parse, callback, seeking-hint, and worker-control seams from the Remotion media-parser lane for bounded HyperTwist media inspection.")
			)
		),
		MakePackageReference(
			TEXT("package/remotion-studio-api"),
			TEXT("Studio preview and output-registration API surfaces"),
			TEXT("./packages/studio/src/api"),
			TEXT("bounded-explainer-studio-reference"),
			TEXT("MIT package surface, but full studio workflows still depend on custom-licensed player and renderer packages"),
			TEXT("Preview transport, play-pause-seek controls, output upload and client-render registration, visual-control wiring, and default-props update seams for first-party HyperTwist replay explainer sidecars."),
			{TEXT("explainer-studio"), TEXT("preview-transport"), TEXT("output-registration")},
			{
				TEXT("whole authoring shell inheritance"),
				TEXT("template or editor shell ownership"),
				TEXT("direct donor API and file layout preservation")
			},
			MakeAttribution(
				TEXT("media-export/studio-api"),
				TEXT("Preserves bounded studio preview, output-registration, and prop-editing seams from the retained Remotion studio API lane without inheriting the whole authoring shell.")
			)
		)
	};

	FHyperTwistTrainingEmbeddedPlaybackContract EmbeddedPlayback;
	EmbeddedPlayback.ContractId = TEXT("remotion-embedded-playback-and-controls");
	EmbeddedPlayback.Title = TEXT("Embedded playback and controls");
	EmbeddedPlayback.Summary = TEXT("First-party HyperTwist embedded-playback contract preserving explicit composition dimensions, frame-bounded transport, custom controls, poster behavior, buffering posture, and playback-rate handling from the retained Remotion player lane.");
	EmbeddedPlayback.SupportedControlKinds =
	{
		TEXT("play and pause"),
		TEXT("toggle play state"),
		TEXT("seek to frame"),
		TEXT("fullscreen toggle"),
		TEXT("mute and volume control"),
		TEXT("playback-rate selection"),
		TEXT("custom control injection"),
		TEXT("thumbnail and poster surfaces")
	};
	EmbeddedPlayback.TimelineStateRules =
	{
		TEXT("keep duration, fps, composition width, and composition height explicit rather than inferred from a broader authoring shell"),
		TEXT("validate initialFrame, inFrame, and outFrame against duration bounds before playback starts"),
		TEXT("treat player frame state, playing state, and imperative ref state as separate concerns"),
		TEXT("preserve shared-audio-tag budgeting and click, space, or fullscreen control toggles as opt-in transport behaviors")
	};
	EmbeddedPlayback.PosterAndBufferRules =
	{
		TEXT("preserve separate poster posture for unplayed, paused, ended, buffering, and buffering-while-paused states"),
		TEXT("support explicit buffering delay and hide-controls-when-pointer-stops-moving posture"),
		TEXT("keep overflow-visible and player-size poster-fill behavior as first-party presentation options rather than donor shell assumptions")
	};
	EmbeddedPlayback.PlaybackStateRules =
	{
		TEXT("preserve validated playback-rate updates instead of letting arbitrary rates drift into transport state"),
		TEXT("persist audio and volume posture only behind an explicit persistence key"),
		TEXT("treat acknowledge-license and log-level behaviors as boundary concerns, not as mandatory user-facing donor messaging")
	};
	EmbeddedPlayback.ApprovedWorkflowTags =
	{
		TEXT("embedded-playback"),
		TEXT("replay-explainer"),
		TEXT("timeline-controls"),
		TEXT("bounded-preview")
	};
	EmbeddedPlayback.ExplicitExclusions =
	{
		TEXT("whole React player shell inheritance"),
		TEXT("generic video-site or template ownership"),
		TEXT("broad runtime foundation ownership")
	};
	EmbeddedPlayback.SourceAttribution = MakeAttribution(
		TEXT("media-export/embedded-playback"),
		TEXT("Preserves embedded player dimensions, transport, poster, buffering, and custom-control seams from the retained Remotion player lane for first-party HyperTwist replay explainer use.")
	);
	Bundle.EmbeddedPlaybackContracts = {EmbeddedPlayback};

	FHyperTwistTrainingRenderOrchestrationContract RenderOrchestration;
	RenderOrchestration.ContractId = TEXT("remotion-render-orchestration-and-export");
	RenderOrchestration.Title = TEXT("Render orchestration and export");
	RenderOrchestration.Summary = TEXT("First-party HyperTwist render-orchestration contract preserving codec-aware export validation, browser-backed render flow, progress callbacks, cancellation, and output-location discipline from the retained Remotion renderer lane.");
	RenderOrchestration.SupportedCodecFamilies =
	{
		TEXT("h264"),
		TEXT("h265"),
		TEXT("av1"),
		TEXT("vp8"),
		TEXT("vp9"),
		TEXT("prores"),
		TEXT("gif"),
		TEXT("audio-only codecs and explicit audio-codec pairing")
	};
	RenderOrchestration.ValidationRules =
	{
		TEXT("validate output filename against codec and audio-codec extension rules"),
		TEXT("validate even-dimension constraints for codecs that require them"),
		TEXT("validate selected pixel format and codec or image-format combinations"),
		TEXT("validate CRF, bitrate, scale, frame-range, and composition-start posture before launching export"),
		TEXT("treat serveUrl, browser executable, and concurrency settings as explicit first-party sidecar parameters")
	};
	RenderOrchestration.ProgressAndCancellationRules =
	{
		TEXT("preserve staged progress reporting across rendered frames, encoded frames, and stitch stage"),
		TEXT("treat cancelSignal as a first-class export outcome rather than an afterthought"),
		TEXT("preserve explicit onStart, onDownload, onBrowserLog, and artifact callbacks for operator-visible export lifecycle review"),
		TEXT("keep browser download and ffmpeg or compositor preparation behind explicit orchestration steps")
	};
	RenderOrchestration.OutputRules =
	{
		TEXT("preserve overwrite posture as an explicit choice"),
		TEXT("treat outputLocation as a bounded sidecar artifact sink rather than a donor shell convention"),
		TEXT("preserve fast-start and seamless-concat decisions as codec-aware export policy rather than fixed behavior"),
		TEXT("separate preview-time composition props from serialized resolved export props")
	};
	RenderOrchestration.ApprovedWorkflowTags =
	{
		TEXT("media-export"),
		TEXT("render-orchestration"),
		TEXT("progress-reporting"),
		TEXT("replay-recap")
	};
	RenderOrchestration.ExplicitExclusions =
	{
		TEXT("whole Node or Bun render-service shell"),
		TEXT("hosted cloud render platform ownership"),
		TEXT("direct donor CLI adoption")
	};
	RenderOrchestration.SourceAttribution = MakeAttribution(
		TEXT("media-export/render-orchestration"),
		TEXT("Preserves codec-aware validation, staged progress, cancellation, and export-output seams from the retained Remotion renderer lane for first-party HyperTwist media-export workflows.")
	);
	Bundle.RenderOrchestrationContracts = {RenderOrchestration};

	FHyperTwistTrainingMediaParserContract MediaParser;
	MediaParser.ContractId = TEXT("remotion-media-parser-and-worker-seeking");
	MediaParser.Title = TEXT("Media parser and worker seeking");
	MediaParser.Summary = TEXT("First-party HyperTwist media-parser contract preserving metadata callbacks, track discovery, worker forwarding, seeking hints, and controller lifecycle seams from the retained Remotion media-parser lane.");
	MediaParser.SupportedFieldFamilies =
	{
		TEXT("container, mime type, and location"),
		TEXT("duration, fps, dimensions, rotation, and HDR"),
		TEXT("audio and video codec details"),
		TEXT("track manifests and keyframes"),
		TEXT("sample rate, channel count, and track-level metadata"),
		TEXT("slow-structure and parse-progress telemetry")
	};
	MediaParser.CallbackFamilies =
	{
		TEXT("onMetadata and onTracks"),
		TEXT("onAudioTrack and onVideoTrack"),
		TEXT("onDurationInSeconds, onFps, onDimensions, and onRotation"),
		TEXT("onParseProgress and onInternalStats"),
		TEXT("onSlowStructure and related slow-field callbacks")
	};
	MediaParser.SeekingAndWorkerRules =
	{
		TEXT("preserve controller-driven pause, resume, seek, abort, and seeking-hint flows"),
		TEXT("support worker, server-worker, node, web, and universal entry-point boundaries where the first-party sidecar actually needs them"),
		TEXT("treat M3U stream selection and associated-playlist decisions as explicit policy inputs"),
		TEXT("preserve makeSamplesStartAtZero and progress-interval posture as first-party export-preflight options")
	};
	MediaParser.ControllerLifecycleRules =
	{
		TEXT("forward pause, resume, seek, get-seeking-hints, simulate-seek, and abort requests through explicit controller or worker messages"),
		TEXT("treat negative seek requests and impossible seek resolution as explicit failures"),
		TEXT("preserve seeking-hint extraction as a bounded optimization surface instead of a donor parser API obligation")
	};
	MediaParser.ApprovedWorkflowTags =
	{
		TEXT("media-parser"),
		TEXT("track-inspection"),
		TEXT("worker-seeking"),
		TEXT("export-preflight")
	};
	MediaParser.ExplicitExclusions =
	{
		TEXT("whole generic media processing platform ownership"),
		TEXT("direct donor parser API preservation"),
		TEXT("broad standalone media tooling identity")
	};
	MediaParser.SourceAttribution = MakeAttribution(
		TEXT("media-export/media-parser-contract"),
		TEXT("Preserves metadata callbacks, controller lifecycle, worker forwarding, and seeking-hint seams from the retained Remotion media-parser lane for first-party HyperTwist export and replay inspection.")
	);
	Bundle.MediaParserContracts = {MediaParser};

	FHyperTwistTrainingExplainerStudioContract ExplainerStudio;
	ExplainerStudio.ContractId = TEXT("remotion-explainer-studio-preview-and-output-registration");
	ExplainerStudio.Title = TEXT("Explainer studio preview and output registration");
	ExplainerStudio.Summary = TEXT("First-party HyperTwist explainer-studio contract preserving preview transport, output upload and client-render registration, visual-control editing, and default-props update posture from the retained Remotion studio API lane.");
	ExplainerStudio.TimelineInteractionRules =
	{
		TEXT("preserve explicit play, pause, and seek-to-frame preview transport calls"),
		TEXT("clamp negative seek targets to zero"),
		TEXT("keep preview-time transport separate from export-time orchestration"),
		TEXT("treat renderEntry and previewEntry split as a bounded sidecar distinction rather than a whole authoring-shell commitment")
	};
	ExplainerStudio.ClientRenderRegistrationRules =
	{
		TEXT("upload output artifacts through an explicit filePath-targeted output endpoint"),
		TEXT("register and unregister completed client renders as explicit side effects"),
		TEXT("surface non-OK output and registration responses as structured first-party errors")
	};
	ExplainerStudio.PropEditingRules =
	{
		TEXT("preserve visual-control override posture only when not rendering"),
		TEXT("treat updateDefaultProps as an alias to the persisted saveDefaultProps flow"),
		TEXT("keep default-props editing, schema wiring, and visual-control state as bounded explainer-authoring seams rather than runtime ownership")
	};
	ExplainerStudio.ApprovedWorkflowTags =
	{
		TEXT("explainer-studio"),
		TEXT("preview-transport"),
		TEXT("output-registration"),
		TEXT("prop-editing")
	};
	ExplainerStudio.ExplicitExclusions =
	{
		TEXT("whole authoring shell inheritance"),
		TEXT("template ecosystem ownership"),
		TEXT("broad studio product identity")
	};
	ExplainerStudio.SourceAttribution = MakeAttribution(
		TEXT("media-export/explainer-studio"),
		TEXT("Preserves bounded preview transport, output registration, visual-control, and default-props seams from the retained Remotion studio API lane for first-party HyperTwist replay explainers.")
	);
	Bundle.ExplainerStudioContracts = {ExplainerStudio};

	FHyperTwistTrainingMediaExportComplianceBoundary ComplianceBoundary;
	ComplianceBoundary.BoundaryId = TEXT("remotion-commercial-sidecar-and-package-split-boundary");
	ComplianceBoundary.Title = TEXT("Remotion commercial sidecar and package-split boundary");
	ComplianceBoundary.Summary = TEXT("First-party HyperTwist compliance boundary for using bounded Remotion package value in a commercially sensitive sidecar lane while keeping direct package usage subject to the checked company-license eligibility rules and keeping the broader authoring shell outside the landed lane.");
	ComplianceBoundary.AllowedSourceRoots =
	{
		TEXT("./packages/player"),
		TEXT("./packages/renderer"),
		TEXT("./packages/media-parser"),
		TEXT("./packages/studio/src/api")
	};
	ComplianceBoundary.ExcludedSourceRoots =
	{
		TEXT("./packages/template-recorder"),
		TEXT("./packages/template-tiktok"),
		TEXT("./packages/template-audiogram"),
		TEXT("./packages/template-vercel"),
		TEXT("./packages/cloudrun"),
		TEXT("./packages/lambda"),
		TEXT("./packages/serverless"),
		TEXT("./packages/promo-pages"),
		TEXT("./packages/create-video")
	};
	ComplianceBoundary.RequiredNoticeActions =
	{
		TEXT("preserve the checked root LICENSE.md and keep the two-tier commercial terms explicit in packet docs, manifests, and future widening notes"),
		TEXT("do not describe player, renderer, or media-parser as MIT-only surfaces when their package metadata points back to the checked Remotion license posture"),
		TEXT("confirm direct package-shipping eligibility or company-license obligation for the exact package set before commercial deployment outside the checked free-use bracket"),
		TEXT("keep the landed lane described as a bounded first-party media-export and explainer sidecar rather than a runtime foundation")
	};
	ComplianceBoundary.ProvenanceCaveats =
	{
		TEXT("free use in the checked mirror is limited to individuals, non-profits, evaluation use, and for-profit organizations with up to 3 employees"),
		TEXT("@remotion/studio exposes MIT, but the retained package set still includes player, renderer, and media-parser surfaces that point back to the checked Remotion license posture"),
		TEXT("the retained value is generated coaching media, replay explainers, bounded playback, and parser or renderer orchestration rather than whole authoring-shell ownership"),
		TEXT("HyperTwist should preserve the export and explainer seams in first-party contracts rather than inherit the broader template or cloud deployment model")
	};
	ComplianceBoundary.ExplicitExclusions =
	{
		TEXT("whole authoring shell adoption"),
		TEXT("template and showcase ecosystem inheritance"),
		TEXT("cloud render, lambda, or hosted deployment platform ownership"),
		TEXT("carefree direct use outside the checked free-license eligibility bracket")
	};
	ComplianceBoundary.SourceAttribution = MakeAttribution(
		TEXT("media-export/compliance-boundary"),
		TEXT("Preserves the Remotion package split and checked commercial-license boundary so HyperTwist can land bounded first-party export and explainer contracts without flattening the company-license posture.")
	);
	Bundle.ComplianceBoundaries = {ComplianceBoundary};

	return Bundle;
}

bool UHyperTwistTrainingMediaExportLibrary::TryGetPackageReferenceById(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle,
	const FString& PackageId,
	FHyperTwistTrainingMediaExportPackageReference& OutReference
)
{
	for (const FHyperTwistTrainingMediaExportPackageReference& Reference : Bundle.PackageReferences)
	{
		if (Reference.PackageId.Equals(PackageId, ESearchCase::IgnoreCase))
		{
			OutReference = Reference;
			return true;
		}
	}

	OutReference = FHyperTwistTrainingMediaExportPackageReference();
	return false;
}

bool UHyperTwistTrainingMediaExportLibrary::TryGetEmbeddedPlaybackContractById(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingEmbeddedPlaybackContract& OutContract
)
{
	for (const FHyperTwistTrainingEmbeddedPlaybackContract& Contract : Bundle.EmbeddedPlaybackContracts)
	{
		if (Contract.ContractId.Equals(ContractId, ESearchCase::IgnoreCase))
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingEmbeddedPlaybackContract();
	return false;
}

bool UHyperTwistTrainingMediaExportLibrary::TryGetRenderOrchestrationContractById(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingRenderOrchestrationContract& OutContract
)
{
	for (const FHyperTwistTrainingRenderOrchestrationContract& Contract : Bundle.RenderOrchestrationContracts)
	{
		if (Contract.ContractId.Equals(ContractId, ESearchCase::IgnoreCase))
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingRenderOrchestrationContract();
	return false;
}

bool UHyperTwistTrainingMediaExportLibrary::TryGetMediaParserContractById(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingMediaParserContract& OutContract
)
{
	for (const FHyperTwistTrainingMediaParserContract& Contract : Bundle.MediaParserContracts)
	{
		if (Contract.ContractId.Equals(ContractId, ESearchCase::IgnoreCase))
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingMediaParserContract();
	return false;
}

bool UHyperTwistTrainingMediaExportLibrary::TryGetExplainerStudioContractById(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle,
	const FString& ContractId,
	FHyperTwistTrainingExplainerStudioContract& OutContract
)
{
	for (const FHyperTwistTrainingExplainerStudioContract& Contract : Bundle.ExplainerStudioContracts)
	{
		if (Contract.ContractId.Equals(ContractId, ESearchCase::IgnoreCase))
		{
			OutContract = Contract;
			return true;
		}
	}

	OutContract = FHyperTwistTrainingExplainerStudioContract();
	return false;
}

bool UHyperTwistTrainingMediaExportLibrary::TryGetComplianceBoundaryById(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle,
	const FString& BoundaryId,
	FHyperTwistTrainingMediaExportComplianceBoundary& OutBoundary
)
{
	for (const FHyperTwistTrainingMediaExportComplianceBoundary& Boundary : Bundle.ComplianceBoundaries)
	{
		if (Boundary.BoundaryId.Equals(BoundaryId, ESearchCase::IgnoreCase))
		{
			OutBoundary = Boundary;
			return true;
		}
	}

	OutBoundary = FHyperTwistTrainingMediaExportComplianceBoundary();
	return false;
}

FString UHyperTwistTrainingMediaExportLibrary::BuildPackageChecklistTsv(
	const FHyperTwistTrainingMediaExportReferenceBundle& Bundle
)
{
	FString Output = TEXT("package_id\tlabel\tpackage_path\tusage_posture\tlicense_posture\tsummary\n");
	for (const FHyperTwistTrainingMediaExportPackageReference& Reference : Bundle.PackageReferences)
	{
		if (!Reference.IsStructurallyValid())
		{
			continue;
		}

		Output.Append(Reference.PackageId);
		Output.Append(TEXT("\t"));
		Output.Append(Reference.Label);
		Output.Append(TEXT("\t"));
		Output.Append(Reference.PackagePath);
		Output.Append(TEXT("\t"));
		Output.Append(Reference.UsagePosture);
		Output.Append(TEXT("\t"));
		Output.Append(Reference.LicensePosture);
		Output.Append(TEXT("\t"));
		Output.Append(Reference.Summary.Replace(TEXT("\t"), TEXT(" ")));
		Output.Append(TEXT("\n"));
	}

	return Output;
}
