// ***********************************************************************
// 
//     AgileWebs
// 
// ***********************************************************************
using Microsoft.AspNetCore.Http;
using Serilog;
using System.Text.Json;
namespace Core.Blueprint.Logging
{
    /// 
    /// Handles HTTP logging.
    /// 
    public class HttpErrorMiddleware
    {
        private readonly ILogger logger;
        private readonly RequestDelegate requestProcess;
        public readonly ServiceSettings settings;
        /// 
        /// Creates a new instrance of .
        /// 
        /// The logger representig an instance of .
        /// The request delegate process.
        public HttpErrorMiddleware(ILogger logger, RequestDelegate requestProcess, ServiceSettings settings)
        {
            this.logger = logger;
            this.requestProcess = requestProcess;
            this.settings = settings;
        }
        /// 
        /// Invoke method.
        /// 
        /// The HTTP context.
        /// A  representing the asynchronous operation.
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await requestProcess(context).ConfigureAwait(false);
            }
            catch (HttpException exception)
            {
                await HandleErrorResponse(
                    context,
                    exception.Message,
                    exception.ErrorCode,
                    exception.StatusCode).ConfigureAwait(false);
            }
            catch (Exception defaultException)
            {
                await HandleErrorResponse(
                    context,
                    defaultException.Message,
                    ErrorCodes.InternalServerError,
                    StatusCodes.Status500InternalServerError).ConfigureAwait(false);
            }
        }
        /// 
        /// Handles error responses.
        /// 
        /// The HTTP context.
        /// The error message.
        /// The error code.
        /// The HTTP status code.
        /// A  representing the asynchronous operation.
        private async Task HandleErrorResponse(HttpContext context, string? message, string? errorCode, int statusCode)
        {
            var errorMessage = new HttpError(
                message,
                errorCode,
                string.Format(
                    Responses.Target,
                    context.Request.Method,
                    context.Request.Scheme,
                    context.Request.Host.Host,
                    context.Request.Path));
            logger.LogError(context, errorMessage, $"{settings.ApplicationName}-{settings.LayerName}");
            context.Response.ContentType = MimeTypes.ApplicationJson;
            context.Response.StatusCode = statusCode;
            await context.Response.WriteAsync(JsonSerializer.Serialize(errorMessage)).ConfigureAwait(false);
        }
    }
}