using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using StellaOps.Vexer.Core;

namespace StellaOps.Vexer.Policy;

internal static class VexPolicyDigest
{
    public static string Compute(VexConsensusPolicyOptions options)
    {
        ArgumentNullException.ThrowIfNull(options);

        var builder = new StringBuilder();
        builder.Append(options.Version).Append('|')
            .Append(options.VendorWeight.ToString("F6", CultureInfo.InvariantCulture)).Append('|')
            .Append(options.DistroWeight.ToString("F6", CultureInfo.InvariantCulture)).Append('|')
            .Append(options.PlatformWeight.ToString("F6", CultureInfo.InvariantCulture)).Append('|')
            .Append(options.HubWeight.ToString("F6", CultureInfo.InvariantCulture)).Append('|')
            .Append(options.AttestationWeight.ToString("F6", CultureInfo.InvariantCulture));

        foreach (var kvp in options.ProviderOverrides
                     .OrderBy(static pair => pair.Key, StringComparer.Ordinal))
        {
            builder.Append('|')
                .Append(kvp.Key)
                .Append('=')
                .Append(kvp.Value.ToString("F6", CultureInfo.InvariantCulture));
        }

        var input = builder.ToString();
        var hash = SHA256.HashData(Encoding.UTF8.GetBytes(input));
        return Convert.ToHexString(hash);
    }
}
