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;

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 = "{TokenUserRealName} {TokenUserTypeShortName}  {ClientIp} {LocalIP} {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);

                    //diagnosticContext.Set("Protocol", request.Protocol);
                    //diagnosticContext.Set("Scheme", request.Scheme);

                    // 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);
                    }

                    // Set the content-type of the Response at this point
                    diagnosticContext.Set("ContentType", httpContext.Response.ContentType);

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

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

                    // Retrieve the IEndpointFeature selected for the request
                    var endpoint = httpContext.GetEndpoint();
                    if (endpoint is object) // endpoint != null
                    {
                        diagnosticContext.Set("EndpointName", endpoint.DisplayName);
                    }

                    #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


                };
            });



        }
    }
}