using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;
namespace ShareeBike.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; }
}
}