using Metin2Launcher.Manifest;

namespace Metin2Launcher.Formats;

/// <summary>
/// Strategy that knows how to interpret the <c>files</c> array of a
/// signature-verified manifest. Added for the m2pack migration:
///
///   - <c>legacy-json-blob</c> ships individual files that replace their
///     counterparts inside the client root one-for-one.
///   - <c>m2pack</c> ships <c>.m2p</c> pack archives and a <c>runtime-key.json</c>
///     sidecar. The archives are placed next to the client root and the
///     runtime key is forwarded to the game process via env vars — the
///     launcher NEVER opens, decrypts or decompresses an <c>.m2p</c> archive.
///
/// Both implementations share the same download/apply plumbing in
/// <see cref="Orchestration.UpdateOrchestrator"/>. This interface only
/// captures the pieces that actually differ between the two formats.
/// </summary>
public interface IReleaseFormat
{
    /// <summary>Identifier matching <see cref="Manifest.EffectiveFormat"/>.</summary>
    string Name { get; }

    /// <summary>
    /// Filters the manifest file list down to entries that should be
    /// downloaded on the given platform. Both formats currently delegate
    /// to <see cref="ManifestFile.AppliesTo(string)"/>; the indirection
    /// exists so a future format can special-case (e.g. exclude the
    /// runtime key from platform filtering, or reject unknown kinds).
    /// </summary>
    IReadOnlyList<ManifestFile> FilterApplicable(Manifest.Manifest manifest, string platform);

    /// <summary>
    /// Runs after the apply phase succeeds. The legacy format is a no-op;
    /// the m2pack format loads the runtime key from the client root and
    /// stores it on <paramref name="outcome"/> so the caller can forward it
    /// to the game process.
    /// </summary>
    void OnApplied(string clientRoot, LoadedManifest manifest, ReleaseOutcome outcome);
}

/// <summary>
/// Mutable bag of results emitted by <see cref="IReleaseFormat.OnApplied"/>.
/// Kept separate from the update orchestrator's own <c>Result</c> record so
/// format-specific data doesn't leak into the generic update flow.
/// </summary>
public sealed class ReleaseOutcome
{
    /// <summary>Populated by the m2pack format; null for legacy releases.</summary>
    public Runtime.RuntimeKey? RuntimeKey { get; set; }
}
