using FrameProcessor.Configuration;
using FrameProcessor.Domain;
using Microsoft.Extensions.Options;

namespace FrameProcessor.Middleware;

/// <summary>
/// Enforces an <c>X-Api-Key</c> header on <c>/api/*</c> requests. Other paths
/// (notably <c>/i/{mac}.png</c> and <c>/health</c>) pass through untouched.
/// When the configured key is empty the middleware is a no-op.
/// </summary>
public sealed class ApiKeyMiddleware
{
    private const string HeaderName = "X-Api-Key";
    private readonly RequestDelegate _next;
    private readonly IOptionsMonitor<ApiKeyOptions> _options;

    public ApiKeyMiddleware(RequestDelegate next, IOptionsMonitor<ApiKeyOptions> options)
    {
        _next = next;
        _options = options;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase))
        {
            await _next(context).ConfigureAwait(false);
            return;
        }

        var configured = _options.CurrentValue.Value;
        if (string.IsNullOrEmpty(configured))
        {
            await _next(context).ConfigureAwait(false);
            return;
        }

        var provided = context.Request.Headers[HeaderName].ToString();
        if (!new ApiKey(configured).Matches(provided))
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return;
        }

        await _next(context).ConfigureAwait(false);
    }
}
