using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace StellaOps.Feedser.Exporter.Json;

public static class ExportDigestCalculator
{
    public static string ComputeTreeDigest(JsonExportResult result)
    {
        ArgumentNullException.ThrowIfNull(result);

        using var sha256 = SHA256.Create();
        var buffer = new byte[128 * 1024];

        foreach (var file in result.FilePaths.OrderBy(static path => path, StringComparer.Ordinal))
        {
            var normalized = file.Replace("\\", "/");
            var pathBytes = Encoding.UTF8.GetBytes(normalized);
            _ = sha256.TransformBlock(pathBytes, 0, pathBytes.Length, null, 0);

            var fullPath = ResolveFullPath(result.ExportDirectory, normalized);
            using var stream = File.OpenRead(fullPath);
            int read;
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                _ = sha256.TransformBlock(buffer, 0, read, null, 0);
            }
        }

        _ = sha256.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
        var hash = sha256.Hash ?? Array.Empty<byte>();
        var hex = Convert.ToHexString(hash).ToLowerInvariant();
        return $"sha256:{hex}";
    }

    private static string ResolveFullPath(string root, string normalizedRelativePath)
    {
        var segments = normalizedRelativePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
        var parts = new string[segments.Length + 1];
        parts[0] = root;
        for (var i = 0; i < segments.Length; i++)
        {
            parts[i + 1] = segments[i];
        }

        return Path.Combine(parts);
    }
}
