using System.Security.Cryptography;

namespace PSLauncher.Core.Integrity;

public sealed class IntegrityService : IIntegrityService
{
    public async Task<string> ComputeSha256Async(string filePath, IProgress<double>? progress, CancellationToken ct)
    {
        const int bufferSize = 1 << 20; // 1 MiB
        await using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync: true);
        using var sha = SHA256.Create();

        var buffer = new byte[bufferSize];
        long total = fs.Length;
        long read = 0;
        int n;
        while ((n = await fs.ReadAsync(buffer.AsMemory(0, bufferSize), ct).ConfigureAwait(false)) > 0)
        {
            sha.TransformBlock(buffer, 0, n, null, 0);
            read += n;
            if (total > 0) progress?.Report((double)read / total);
        }
        sha.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
        return Convert.ToHexString(sha.Hash!).ToLowerInvariant();
    }
}
