using System.Security.Cryptography;
using System.Text;

namespace ZB.MOM.WW.Auth.ApiKeys;

internal static class ApiKeySecretHasher
{
    /// <summary>
    /// Computes HMAC-SHA256(key: UTF-8(pepper), data: UTF-8(secret)).
    /// </summary>
    public static byte[] Hash(string secret, string pepper)
    {
        byte[] pepperBytes = Encoding.UTF8.GetBytes(pepper);
        byte[] secretBytes = Encoding.UTF8.GetBytes(secret);

        using HMACSHA256 hmac = new(pepperBytes);
        return hmac.ComputeHash(secretBytes);
    }

    /// <summary>
    /// Returns true iff HMAC-SHA256(key: UTF-8(pepper), data: UTF-8(secret)) equals
    /// <paramref name="expectedHash"/>, using a constant-time comparison.
    /// Returns false (without throwing) if the lengths differ.
    /// </summary>
    public static bool Verify(string secret, string pepper, byte[] expectedHash)
    {
        byte[] actualHash = Hash(secret, pepper);
        return CryptographicOperations.FixedTimeEquals(actualHash, expectedHash);
    }
}
