using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Filters.Infrastructure
{
    public class TimeFilter : IAsyncActionFilter, IAsyncResultFilter
    {
        private ConcurrentQueue<double> actionTimes
            = new ConcurrentQueue<double>();
        private ConcurrentQueue<double> resultTimes
            = new ConcurrentQueue<double>();
        private IFilterDiagnostics diagnostics;

        public TimeFilter(IFilterDiagnostics diags)
        {
            diagnostics = diags;
        }

        public async Task OnActionExecutionAsync(
              ActionExecutingContext context, ActionExecutionDelegate next)
        {
            Stopwatch timer = Stopwatch.StartNew();
            await next();
            timer.Stop();
            actionTimes.Enqueue(timer.Elapsed.TotalMilliseconds);
            diagnostics.AddMessage($@"Czas wykonania filtru akcji: 
                 {timer.Elapsed.TotalMilliseconds}ms,
                  średnio: {actionTimes.Average():F2}ms.");
        }

        public async Task OnResultExecutionAsync(
              ResultExecutingContext context, ResultExecutionDelegate next)
        {
            Stopwatch timer = Stopwatch.StartNew();
            await next();
            timer.Stop();
            resultTimes.Enqueue(timer.Elapsed.TotalMilliseconds);
            diagnostics.AddMessage($@"Czas wykonania filtru wyniku: 
                 {timer.Elapsed.TotalMilliseconds}ms, 
                  średnio: {resultTimes.Average():F2}ms.");
        }
    }
}