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

namespace FrameProcessor.Domain;

/// <summary>
/// Wraps the shared API key. <see cref="Matches"/> uses a constant-time comparison
/// over UTF-8 bytes to avoid leaking key length or content via timing side channels.
/// </summary>
public readonly record struct ApiKey
{
    private readonly string? _value;

    public ApiKey(string value)
    {
        ArgumentNullException.ThrowIfNull(value);
        _value = value;
    }

    public string Value => _value ?? string.Empty;

    public bool Matches(string? candidate)
    {
        if (candidate is null)
        {
            return false;
        }

        var expectedBytes = Encoding.UTF8.GetBytes(Value);
        var candidateBytes = Encoding.UTF8.GetBytes(candidate);
        return CryptographicOperations.FixedTimeEquals(expectedBytes, candidateBytes);
    }
}
