using Microsoft.AspNetCore.Http;
using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Waste.Core
{
    public static class LoggerHelper
    {
        public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
        {
            var request = httpContext.Request;

            // Set all the common properties available for every request
            diagnosticContext.Set("Host", request.Host);
            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);
            }
            string ip = string.Empty;
            if (request.Headers.ContainsKey("X-Real-IP"))
            {
                ip = request.Headers["X-Real-IP"].ToString();
            }
            else
            {
                ip = httpContext.Connection.RemoteIpAddress.ToString();
            }
            if (!string.IsNullOrEmpty(ip))
            {
                diagnosticContext.Set("IP", ip);
            }
            if (!string.IsNullOrEmpty(request.Headers["token"].ToString()))
            {
                diagnosticContext.Set("token", request.Headers["token"].ToString());
            }
            if (!string.IsNullOrEmpty(request.Headers["Authorization"].ToString()))
            {
                diagnosticContext.Set("Authorization", request.Headers["Authorization"].ToString());
            }
            if (!string.IsNullOrEmpty(request.Headers["X-Authorization"].ToString()))
            {
                diagnosticContext.Set("X-Authorization", request.Headers["X-Authorization"].ToString());
            }
            if (!string.IsNullOrEmpty(request.Headers["User-Agent"].ToString()))
            {
                diagnosticContext.Set("UserAgent", request.Headers["User-Agent"].ToString());
            }
            if (request.Method == "POST" && request.ContentLength > 0)
            {
                if (httpContext.RequestAborted.IsCancellationRequested)
                {
                    diagnosticContext.Set("postdata", "用户取消了操作");
                }
                else
                {
                    string postdata = string.Empty;
                    try
                    {
                        if (request.Body.Length > 0)
                        {
                            request.EnableBuffering();
                            request.Body.Position = 0;
                            using (var sr = new StreamReader(request.Body))
                            {
                                postdata = Task.Factory.StartNew(sr.ReadToEndAsync, TaskCreationOptions.LongRunning)
                                    .GetAwaiter().GetResult().Result;
                                // postdata = await sr.ReadToEndAsync();
                            }
                            if (!string.IsNullOrEmpty(postdata))
                            {
                                diagnosticContext.Set("PostData", postdata);
                            }
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            // Set the content-type of the Response at this point
            diagnosticContext.Set("ContentType", httpContext.Response.ContentType);

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