namespace HttpClientStudy.WebApp
{
    /// <summary>
    /// 接口耗时 中间件
    /// </summary>
    public class UsedTimeMiddleware
    {
        private const string RESPONSE_HEADER_RESPONSE_TIME = "X-WebApi-UseTime";
        private readonly RequestDelegate _next;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="next">下一中间件</param>
        public UsedTimeMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        /// <summary>
        /// 中间件执行方法
        /// </summary>
        /// <param name="context">Http请求上下文</param>
        /// <returns></returns>
        public Task InvokeAsync(HttpContext context)
        {
            var watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            //此时还没结束响应:计进结束偏早,不是太准确
            //可以加个500毫秒平衡一下
            context.Response.OnStarting(() =>
            {
                watch.Stop();
                var responseTimeForCompleteRequest = watch.ElapsedMilliseconds;
                context.Response.Headers[RESPONSE_HEADER_RESPONSE_TIME] = responseTimeForCompleteRequest.ToString();
                return Task.CompletedTask;
            });

            // 响应完成时触发:计时更准确,但此时(绝大部分情况下)已经不能再修改响应头了。只能用在其它方面:如日志记录、统计等。
            context.Response.OnCompleted(() => 
            {
                //context.Response.Headers[RESPONSE_HEADER_RESPONSE_TIME] = "xxxxxx";
                return Task.CompletedTask;
            });

            return this._next(context);
        }
    }
}