using System; using Serilog; using TINK.Model.Bikes.BikeInfoNS.CopriLock; using TINK.Model.Connector; using TINK.Model.Device; using TINK.Model.User; using TINK.View; using TINK.ViewModel.Bikes.Bike.CopriLock.RequestHandler; namespace TINK.ViewModel.Bikes.Bike.CopriLock { public static class RequestHandlerFactory { /// Creates a request handler. /// /// /// /// /// /// Provides info about the smart device (phone, tablet, ...) /// /// View model to be used for progress report and unlocking/ locking view. /// Request handler. public static BluetoothLock.IRequestHandler Create( Model.Bikes.BikeInfoNS.BC.IBikeInfoMutable selectedBike, Func isConnectedDelegate, Func connectorFactory, Func viewUpdateManager, ISmartDevice smartDevice, IViewService viewService, IBikesViewModel bikesViewModel, IUser activeUser) { if (!(selectedBike is IBikeInfoMutable selectedCopriLock)) { Log.Error("Bike of unexpected type {type} detected.", selectedBike?.GetType()); return null; } switch (selectedCopriLock.State.Value) { // User has rented this bike before. Bike is now available but feedback was not yet given. case Model.State.InUseStateEnum.FeedbackPending: return new FeedbackPending( selectedCopriLock, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case Model.State.InUseStateEnum.Disposable: // Bike is reserved, selected action depending on lock state. return new DisposableClosed( selectedCopriLock, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case Model.State.InUseStateEnum.Reserved: // Lock could not be opened after reserving bike. return new ReservedClosed( selectedCopriLock, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case Model.State.InUseStateEnum.Booked: // Bike is booked, selected action depending on lock state. var lockState = selectedCopriLock.LockInfo.State; switch (lockState) { case LockingState.Closed: // Frame lock is closed. User paused ride and closed lock. return new BookedClosed( selectedCopriLock, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); default: if (lockState != LockingState.Open) Log.Error("Unexpected locking {LockingState} of a rented bike with copri lock bike detected.", selectedCopriLock.LockInfo.State); return new BookedOpen( selectedCopriLock, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); } default: // Unexpected copri state detected. Log.Error("Unexpected locking {BookingState}/ {LockingState} of a copri lock bike detected.", selectedCopriLock.State.Value, selectedCopriLock.LockInfo.State); return new DisposableClosed( selectedCopriLock, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); } } } }