using Serilog;
using Serilog.AspNetCore;
using Serilog.Events;
using Tiku.Application.Security;

namespace Tiku.Api.Logging;

public static class SerilogRequestLogging
{
    public static void ConfigureRequestLogging(RequestLoggingOptions options)
    {
        options.GetLevel = (httpContext, elapsed, exception) =>
            exception is not null || httpContext.Response.StatusCode >= StatusCodes.Status500InternalServerError
                ? LogEventLevel.Error
                : elapsed > 1000 || httpContext.Response.StatusCode >= StatusCodes.Status400BadRequest
                    ? LogEventLevel.Warning
                    : LogEventLevel.Information;

        options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
        {
            diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
            diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
            diagnosticContext.Set("TraceId", httpContext.TraceIdentifier);

            var user = httpContext.User;
            SetClaim(diagnosticContext, "UserId", user, TikuClaimTypes.UserId);
            SetClaim(diagnosticContext, "TenantId", user, TikuClaimTypes.TenantId);
            SetClaim(diagnosticContext, "SessionId", user, TikuClaimTypes.SessionId);
            SetClaim(diagnosticContext, "AuthRealm", user, TikuClaimTypes.Realm);
        };
    }

    private static void SetClaim(
        IDiagnosticContext diagnosticContext,
        string propertyName,
        System.Security.Claims.ClaimsPrincipal principal,
        string claimType)
    {
        var value = principal.FindFirst(claimType)?.Value;
        if (!string.IsNullOrWhiteSpace(value))
        {
            diagnosticContext.Set(propertyName, value);
        }
    }
}
