using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace LangGuan.Middleware
{
    /// 
    /// 日志中间件
    /// 
    public class RequestLoggingMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;
        /// 
        /// 计时器
        /// 
        private Stopwatch _stopwatch;
        /// 
        /// 构建中间件
        /// 
        /// 
        /// 
        public RequestLoggingMiddleware(RequestDelegate next, ILogger logger)
        {
            _next = next;
            _logger = logger;
        }
        /// 
        /// task
        /// 
        /// 
        /// 
        public async Task Invoke(HttpContext context)
        {
            var startTime = DateTime.Now;
            string arguments = string.Empty;//入参
            string result = string.Empty;//结果
            _stopwatch = new Stopwatch();
            _stopwatch.Start();
            var response = context.Response.Body;
            long contentLen = context.Request.ContentLength == null ? 0 : context.Request.ContentLength.Value;
            if (contentLen > 0)
            {
                // 启用倒带功能
                context.Request.EnableBuffering();
                // 读取请求体中所有内容
                var stream = context.Request.Body;
                byte[] buffer = new byte[contentLen];
                await stream.ReadAsync(buffer, 0, buffer.Length);
                // 转化为字符串
                arguments = System.Text.Encoding.UTF8.GetString(buffer);
                if (context.Request.Method == "POST" || context.Request.Method == "PUT" || context.Request.Method == "DELETE") context.Request.Body.Position = 0;
            }
            //返回结果
            using (var responseBody = new MemoryStream())
            {
                context.Response.Body = responseBody;
                await _next(context);
                result = await GetResponse(context.Response);
                await responseBody.CopyToAsync(response);
            }
            context.Response.OnCompleted(() =>
            {
                _stopwatch.Stop();
                _logger.LogInformation($"Client IP:[{context.Connection.RemoteIpAddress}] ,\n" +
                 $"Request path:[{context.Request.Path}],\nRequest Method:[{context.Request.Method}],\n" +
                 $"Arguments:[{arguments}],\n Result:[{result}],\nStart time:[{startTime}],\nDuration:[{_stopwatch.ElapsedMilliseconds}]");
                return Task.CompletedTask;
            });
        }
        /// 
        /// 获取响应内容
        /// 
        /// 
        /// 
        public async Task GetResponse(HttpResponse response)
        {
            if (response.Body.Length == 0)
            {
                response.StatusCode = 204;
                return null;
            }
            else
            {
                response.Body.Seek(0, SeekOrigin.Begin);
                var text = await new StreamReader(response.Body).ReadToEndAsync();
                response.Body.Seek(0, SeekOrigin.Begin);
                return text;
            }
        }
    }
}