using System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.Options;
using ZB.MOM.WW.MxGateway.Server.Configuration;

namespace ZB.MOM.WW.MxGateway.Server.Security.Authentication;

public sealed class ApiKeySecretHasher(
    IConfiguration configuration,
    IOptions<GatewayOptions> options) : IApiKeySecretHasher
{
    /// <summary>Hashes an API key secret with pepper using HMAC-SHA256.</summary>
    /// <param name="secret">The secret to hash.</param>
    /// <returns>The hashed secret.</returns>
    public byte[] HashSecret(string secret)
    {
        string pepper = GetPepper();
        byte[] pepperBytes = Encoding.UTF8.GetBytes(pepper);
        byte[] secretBytes = Encoding.UTF8.GetBytes(secret);

        using HMACSHA256 hmac = new(pepperBytes);

        return hmac.ComputeHash(secretBytes);
    }

    private string GetPepper()
    {
        string pepperSecretName = options.Value.Authentication.PepperSecretName;
        string? pepper = configuration[pepperSecretName];

        if (string.IsNullOrWhiteSpace(pepper))
        {
            throw new ApiKeyPepperUnavailableException(pepperSecretName);
        }

        return pepper;
    }
}
