using System;
using System.Diagnostics;
using VCommon.Logging;

namespace VCommon.Diagnostics
{
    public class TimingMeasure : IDisposable
    {
        private readonly Stopwatch _stopwatch = new Stopwatch();

        public TimingMeasure()
        {
            _stopwatch.Start();
        }

        public void Dispose()
        {
            _stopwatch.Stop();
            MeasureResult(_stopwatch.ElapsedMilliseconds);
        }

        protected virtual void MeasureResult(long ms)
        {
        }
    }

    public class TimeoutWarnLog : TimingMeasure
    {
        private readonly object _details;
        public string Tag { get; }
        public int TimeoutMs { get; }

        public TimeoutWarnLog(string tag, int timeoutMs = 100, object details = null)
        {
            _details = details;
            Tag = tag;
            TimeoutMs = timeoutMs;
        }

        protected override void MeasureResult(long ms)
        {
            if (ms > TimeoutMs)
                Logger.Warn($"TimingMeasure Result:{Tag}", new { ms, details = _details });
            //else
            //    Logger.Debug($"TimingMeasure Result:{Tag}", new { ms, details = _details });
        }
    }

    public class TimingMeasureAction : TimingMeasure
    {
        private readonly Action<long> _retrMs;

        public TimingMeasureAction(Action<long> retrMs)
        {
            _retrMs = retrMs;
        }

        protected override void MeasureResult(long ms)
        {
            _retrMs?.Invoke(ms);
        }
    }
}