using IRaCIS.Core.API._PipelineExtensions.Serilog;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Serilog;
using System.Linq;

namespace IRaCIS.Core.API
{


    public static class SerilogConfig
    {

        public static void UseSerilogConfig(this IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseMiddleware<RequestResponseLoggingMiddleware>();

            app.UseSerilogRequestLogging(opts
              =>
            {

                opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms";

                opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
                {

                    var request = httpContext.Request;

                    // Set all the common properties available for every request
                    diagnosticContext.Set("Host", request.Host.Value);


                    // Only set it if available. You're not sending sensitive data in a querystring right?!
                    if (request.QueryString.HasValue)
                    {
                        diagnosticContext.Set("QueryString", request.QueryString.Value);
                    }

                    diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);

                    diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);

                    var clientIp = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault() ??
                      httpContext.Connection.RemoteIpAddress?.ToString();

                    if (clientIp.StartsWith("::ffff:"))
                    {
                        clientIp = clientIp.Substring(7); // 移除前缀
                    }

                    diagnosticContext.Set("UserIp", clientIp);

                    #region 非必要不记录
                    //diagnosticContext.Set("Protocol", request.Protocol);
                    //diagnosticContext.Set("Scheme", request.Scheme);
                    //// Retrieve the IEndpointFeature selected for the request
                    //var endpoint = httpContext.GetEndpoint();
                    //if (endpoint is object) // endpoint != null
                    //{
                    //    diagnosticContext.Set("EndpointName", endpoint.DisplayName);
                    //}
                    // Set the content-type of the Response at this point
                    //diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
                    #endregion


                    #region old 未用
                    //这种获取的Ip不准 配置服务才行
                    //diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());

                    //这种方式可以,但是serilog提供了 就不用了
                    //diagnosticContext.Set("TestIP", httpContext.GetUserIp());

                    //这种方式不行 读取的body为空字符串  必须在中间件中读取
                    //diagnosticContext.Set("RequestBody", await ReadRequestBody(httpContext.Request));
                    //diagnosticContext.Set("RequestBody", RequestPayload);
                    #endregion


                };
            });



        }
    }
}