using System;

namespace Wayne.Lib
{
    /// <summary>
    /// TimeoutInterval to keep track of internal timeouts. This is to be used in-memory, and the internal value could not be
    /// saved external to the process as the implementation uses Environment.TickCount that is not exportable.. 
    /// It measures the time from the object is created until the supplied interval is elapsed. Then IsTimeout property
    /// will change from false to true.
    /// </summary>
    public class TimeoutInterval
    {
        private readonly int startTime;
        private readonly int endTime;

        /// <summary>
        /// Used to enable mocking  Environment tickcount in unit tests.
        /// </summary>
        public static Func<int> TickProvider = () => Environment.TickCount;

        /// <summary>
        /// Constructor taking 
        /// </summary>
        /// <param name="interval"></param>
        public TimeoutInterval(TimeSpan interval)
        {
            startTime = TickProvider();
            unchecked
            {
                endTime = startTime + (int)interval.TotalMilliseconds; //Let it wrap around.
            }
        }

        /// <summary>
        /// Returns a value that tells if the timeout interval has been passed.
        /// </summary>
        public bool IsTimedOut
        {
            get
            {
                var now = TickProvider();

                //Normal case - end time is after start time.
                if (endTime > startTime)
                {
                    return now > endTime;
                }
                else //Other case - we have hit the flip point, so start time is end of the first and start beginning of next.
                {
                    return (now < startTime) && (now > endTime);
                }
            }
        }
    }
}