using Edge.Core.Parser;
using Edge.Core.Parser.BinaryParser.MessageEntity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Edge.Core.Processor
{
    public class Incoming<TMessage> : IDisposable, IIncoming<TMessage> where TMessage : MessageBase
    {
        private DateTime? lastMessageReceivedTime;
        private int eventTimeout;
        private System.Timers.Timer eventTimer;
        private bool longTimeNoSeeEventFired = false;
        private TMessage message;
        public event EventHandler OnMessageIncoming;
        public event EventHandler OnLongTimeNoSeeMessage;

        public bool DisablePropagate { get; set; }
        public virtual TMessage Message
        {
            get { return this.message; }
            set
            {
                this.message = value;
                this.lastMessageReceivedTime = DateTime.Now;
                this.longTimeNoSeeEventFired = false;
                var safe = this.OnMessageIncoming;
                safe?.Invoke(this, null);
            }
        }

        public int LongTimeNoSeeMessageTimeout
        {
            get { return this.eventTimeout; }
            set
            {
                this.eventTimeout = value;
                this.eventTimer?.Stop();
                if (this.eventTimeout > 0)
                {
                    //may set to lower to gain more accuracy.
                    this.eventTimer = new System.Timers.Timer(500);
                    this.eventTimer.Elapsed += (_, __) =>
                    {
                        if (DateTime.Now.Subtract(this.lastMessageReceivedTime ?? DateTime.Now).TotalMilliseconds
                            >= this.eventTimeout)
                        {
                            if (!this.longTimeNoSeeEventFired)
                            {
                                this.longTimeNoSeeEventFired = true;
                                this.OnLongTimeNoSeeMessage?.Invoke(this, null);
                            }
                        }
                    };
                    this.eventTimer.Start();
                }
            }
        }

        public void Dispose()
        {
            this.eventTimer?.Stop();
        }
    }
}