using System.Globalization;

namespace ScoreboardApi
{
    using Microsoft.Extensions.Primitives;
    using ScoreboardApi.Settings;
    //extend to make API keys have "permissions" - readonly/readwrite
    public class ApiKeyAuthMiddleware
    {
        private const string ApiKeyHeader = "x-api-key";
        private readonly RequestDelegate _next;
        private readonly ApplicationSettings settings;

        public ApiKeyAuthMiddleware(RequestDelegate next, ApplicationSettings settings)
        {
            _next = next;
            this.settings = settings;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            //do auth
            if (!IsAuthenticated(context))
            {
                context.Response.Clear();
                context.Response.StatusCode = 401;
                context.Response.ContentType = "text/plain";
                await context.Response.WriteAsync("Unauthorized");
                return;
            }

            // Call the next delegate/middleware in the pipeline.
            await _next(context);
        }

        private bool IsAuthenticated(HttpContext context)
        {
            if (context.Request.Headers.TryGetValue(ApiKeyHeader, out StringValues values))
            {
                if (values.Count > 1)
                {
                    return false;
                }

                string? apiKeyValue = values.First();
                bool parseResult = Guid.TryParse(apiKeyValue, out Guid apiKey);
                if(!parseResult) 
                { 
                    return false; 
                }

                var keyEntry = settings.AllowedApiKeys.FirstOrDefault(x => x.ApiKey == apiKey);
                if(keyEntry == null 
                    || keyEntry.Permission == Permissions.Disallowed)
                {
                    return false;
                }

                if (!RequestIsReading(context.Request) 
                    && keyEntry.Permission == Permissions.ReadOnly)
                {
                    return false;
                }

                return true;
            }

            return false;
        }

        private bool RequestIsReading(HttpRequest request)
        {
            return request.Method == "GET";
        }
            
    }

    public static class ApiKeyAuthMiddlewareExtensions
    {
        public static IApplicationBuilder UseApiKeyAuthentication(
            this IApplicationBuilder builder) =>
            builder.UseMiddleware<ApiKeyAuthMiddleware>();
    }
}