using PSLauncher.Models;

namespace PSLauncher.Core.Downloads;

public interface IDownloadManager
{
    Task<string> DownloadAsync(
        DownloadJob job,
        IProgress<DownloadProgress>? progress,
        CancellationToken ct);

    /// <summary>
    /// Variante avec callback de progression dédié pour la phase de vérification SHA-256.
    /// La phase verify est CPU/IO-bound et peut prendre plusieurs minutes sur un build 14 Go ;
    /// la UI doit pouvoir l'afficher distinctement du DL.
    /// </summary>
    Task<string> DownloadAsync(
        DownloadJob job,
        IProgress<DownloadProgress>? progress,
        IProgress<double>? hashProgress,
        CancellationToken ct);

    /// <summary>Retourne l'état de DL persistant pour cette version, ou null s'il n'y en a pas.</summary>
    DownloadState? GetResumableState(string version);

    /// <summary>Supprime l'état persistant et le fichier partiel associé.</summary>
    void DiscardResumableState(string version);
}

public sealed record DownloadJob(
    string Version,
    Uri Url,
    long ExpectedSize,
    string ExpectedSha256)
{
    /// <summary>
    /// Algo de vérif d'intégrité — "sha256" (défaut) ou "none" pour sauter la vérif.
    /// Pris depuis <see cref="PSLauncher.Models.DownloadDescriptor.HashAlgorithm"/>.
    /// </summary>
    public string? HashAlgorithm { get; init; }

    /// <summary>
    /// Callback pour obtenir une URL HMAC-signée fraîche en cas d'expiration mid-DL
    /// (le DL d'un 14 Go sur connexion lente peut dépasser le TTL serveur de 6 h).
    /// Le DownloadManager appelle ce callback quand un segment reçoit un 403/410
    /// (indices d'URL expirée), récupère une URL fraîche, et reprend transparemment
    /// le DL sans l'interrompre. Si null, pas d'auto-refresh : le DL fail proprement.
    /// </summary>
    public Func<CancellationToken, Task<Uri?>>? RefreshUrlAsync { get; init; }
}
