using System; using System.Runtime.Serialization; using Newtonsoft.Json; namespace TINK.Model.State { /// /// Manages state reserved. /// [DataContract] public sealed class StateRequestedInfo : BaseState, IBaseState, INotAvailableState { /// /// Holds the value if time span is not known. /// /// Default value see . public static TimeSpan UNKNOWNMAXRESERVATIONTIMESPAN = TimeSpan.Zero; // Reference to date time provider. private readonly Func _DateTimeNowProvider; /// /// Time span for which a bike can be reserved. Default value is zero. /// public TimeSpan MaxReservationTimeSpan { get; private set; } = UNKNOWNMAXRESERVATIONTIMESPAN; /// /// Prevents an invalid instance to be created. /// Used by serializer only. /// internal StateRequestedInfo() : base(InUseStateEnum.Reserved) { // Is called in context of JSON deserialization. _DateTimeNowProvider = () => DateTime.Now; } /// /// Reservation performed with other device/ before start of app. /// Date time info when bike was reserved has been received from web server. /// /// Time span for which a bike can be reserved. [JsonConstructor] private StateRequestedInfo( InUseStateEnum Value, DateTime From, TimeSpan maxReservationTimeSpan, string MailAddress, string Code) : this(() => DateTime.Now, From, maxReservationTimeSpan, MailAddress, Code) { } /// /// Reservation performed with other device/ before start of app. /// Date time info when bike was reserved has been received from web server. /// /// /// Used to provide current date time information for potential calls of . /// Not used to calculate remaining time because this duration would always be shorter as the one received from web server. /// /// Time span for which a bike can be reserved. public StateRequestedInfo( Func dateTimeNowProvider, DateTime from, TimeSpan maxReservationTimeSpan, string mailAddress, string code) : base(InUseStateEnum.Reserved) { _DateTimeNowProvider = dateTimeNowProvider ?? (() => DateTime.Now); MaxReservationTimeSpan = maxReservationTimeSpan; From = from; MailAddress = mailAddress; Code = code; } /// /// Tries update /// /// True if reservation span has not exceeded and state remains reserved, false otherwise. /// Implement logging of time stamps. public bool GetIsStillReserved(out TimeSpan? remainingTime) { var timeReserved = _DateTimeNowProvider().Subtract(From); if (timeReserved > MaxReservationTimeSpan) { // Reservation has elapsed. Do not update remaining time. remainingTime = null; return false; } remainingTime = MaxReservationTimeSpan - timeReserved; return true; } /// /// State reserved. /// public override InUseStateEnum Value => InUseStateEnum.Reserved; /// /// Date time when bike was reserved. /// [DataMember] public DateTime From { get; } /// /// Mail address of user who reserved the bike. /// [DataMember] public string MailAddress { get; } /// /// Booking code. /// [DataMember] public string Code { get; } } }