using System.Text.Json.Serialization; namespace WiiCompiled.Setup; internal enum RetroWfcPayloadMode { NotApplicable, Online, Skipped } internal sealed class InstallOptions { public required string GamePath { get; init; } /// /// The canonical Retro Rewind installation Wheel Wizard owns. Its resolved path is recorded as /// retro_rewind_root; only its compile inputs are ever snapshotted. /// public string? RetroDirectoryPath { get; init; } public RetroWfcPayloadMode RetroWfcPayloadMode { get; init; } public required string InstallDirectory { get; init; } /// /// Establish a portable installation: the parent of becomes the /// portable root, gets the portable.txt marker and a UserData directory, and all /// runtime user state and [paths] settings stay inside it. /// public bool Portable { get; init; } public bool HasRetroRewind => RetroDirectoryPath is not null; } internal sealed class PayloadManifest { public int SchemaVersion { get; set; } public string ProductVersion { get; set; } = ""; public string ExpectedGameId { get; set; } = "RMCP01"; public string ExpectedDolSha256 { get; set; } = ""; public string ExpectedRelSha256 { get; set; } = ""; public string ToolkitReleaseTag { get; set; } = ""; public string BuildModel { get; set; } = ""; public string RetroWfcPayloadUri { get; set; } = ""; /// /// Content identities computed once at release-build time (Build-Installer.ps1 --emit-payload-identities) /// so install doesn't re-hash gigabytes per user; compilation alone re-derives the toolkit identity from disk. /// public string ToolkitFingerprint { get; set; } = ""; public string ToolkitPackageFingerprint { get; set; } = ""; public string RuntimeAssetsFingerprint { get; set; } = ""; public string TranslationFingerprint { get; set; } = ""; public string NativeToolchainFingerprint { get; set; } = ""; } /// /// One validated, content-identified download in operation-owned scratch space. Callers use this /// exact directory for both the update decision and any resulting build. /// internal sealed record RetroWfcPayloadSnapshot(string Directory, string Sha256, long ByteLength); internal sealed class DiscHeader { [JsonPropertyName("game_id")] public string GameId { get; set; } = ""; [JsonPropertyName("internal_name")] public string InternalName { get; set; } = ""; [JsonPropertyName("region")] public string Region { get; set; } = ""; [JsonPropertyName("revision")] public int Revision { get; set; } } internal sealed class InstallState { [JsonRequired] public int SchemaVersion { get; set; } = 1; /// /// The setup version that produced this installation. This is the field WheelWizard compares /// against the latest published v* release tag; see docs/WHEELWIZARD_CONTRACT.md. /// public string SetupVersion { get; set; } = ProductInfo.Version; public string ProductVersion { get; set; } = ProductInfo.Version; /// The directory this state describes, so a frontend can confirm what it found. public string InstallDir { get; set; } = ""; public DateTime InstalledUtc { get; set; } = DateTime.UtcNow; public bool RetroRewindInstalled { get; set; } public string ToolkitReleaseTag { get; set; } = ""; public string DolSha256 { get; set; } = ""; public string RelSha256 { get; set; } = ""; public string RetroRewindCodePulSha256 { get; set; } = ""; public string RetroRewindCompileInputsSha256 { get; set; } = ""; public string RetroWfcPayloadMode { get; set; } = ""; public string RetroWfcPayloadSha256 { get; set; } = ""; public long RetroWfcPayloadLength { get; set; } /// /// The RetroRewind6 directory this installation was pointed at. The runtime's actual copy is /// [paths] retro_rewind_root; this mirror lets uninstall drop only the setting it owns. /// public string RetroRewindRoot { get; set; } = ""; } /// /// Written next to every locally produced product (Base, RetroRewind): the exact inputs /// it was built from, so launch/update can decide without re-running anything whether it's still correct. /// internal sealed class ProductFingerprint { [JsonRequired] public int SchemaVersion { get; set; } = 1; public string Profile { get; set; } = ""; public string SetupVersion { get; set; } = ProductInfo.Version; public string ToolkitFingerprint { get; set; } = ""; public string DolSha256 { get; set; } = ""; public string RelSha256 { get; set; } = ""; /// /// Identity of the exact executable produced by this build. A valid input provenance is not /// enough if a partial copy, third-party replacement, or disk corruption changed the product /// after it was built. /// public string ExecutableSha256 { get; set; } = ""; public string CodePulSha256 { get; set; } = ""; /// /// Identity of every translator-consumed Retro Rewind input this product was built from. An /// asset-only change to the canonical installation does not alter it, which is exactly why an /// asset-only Retro Rewind update needs no backend work at all. /// public string RetroRewindCompileInputsSha256 { get; set; } = ""; public string RetroWfcPayloadMode { get; set; } = ""; public string RetroWfcPayloadSha256 { get; set; } = ""; public long RetroWfcPayloadLength { get; set; } public DateTimeOffset BuiltUtc { get; set; } = DateTimeOffset.UtcNow; public const string FileName = "build-fingerprint.json"; } /// /// Written whenever the toolkit (translator + build workspace + compiler) is installed or replaced; /// records compile, packaged-tool, and copied-runtime identities. Launch checks compare the compile /// identity against each product's in O(1). /// internal sealed class ToolkitState { [JsonRequired] public int SchemaVersion { get; set; } = 2; public string ToolkitFingerprint { get; set; } = ""; public string ToolkitPackageFingerprint { get; set; } = ""; /// Identity of the runtime assets copied verbatim beside each product. public string RuntimeAssetsFingerprint { get; set; } = ""; public string TranslationFingerprint { get; set; } = ""; public string NativeToolchainFingerprint { get; set; } = ""; public string ToolkitReleaseTag { get; set; } = ""; public string SetupVersion { get; set; } = ProductInfo.Version; public DateTimeOffset UpdatedUtc { get; set; } = DateTimeOffset.UtcNow; public const string FileName = "toolkit-state.json"; }