using System; using TINK.Model.Bike.BluetoothLock; using TINK.Model.Connector; using TINK.Services.BluetoothLock; using TINK.Model.Services.Geolocation; using TINK.View; using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler; using TINK.Model.User; using TINK.MultilingualResources; using Serilog; using TINK.Model.Device; namespace TINK.ViewModel.Bikes.Bike.BluetoothLock { 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 IRequestHandler Create( Model.Bikes.Bike.BC.IBikeInfoMutable selectedBike, Func isConnectedDelegate, Func connectorFactory, IGeolocation geolocation, ILocksService lockService, Func viewUpdateManager, ISmartDevice smartDevice, IViewService viewService, IBikesViewModel bikesViewModel, IUser activeUser) { if (!(selectedBike is Model.Bikes.Bike.BluetoothLock.IBikeInfoMutable selectedBluetoothLockBike)) return null; switch (selectedBluetoothLockBike.State.Value) { case Model.State.InUseStateEnum.Disposable: // Bike is reserved, selecte action depending on lock state. switch (selectedBluetoothLockBike.LockInfo.State) { case LockingState.Closed: // Unexepected state detected. // This state is unexpected because connection is closed // - when reservation is canceled or // - when bike is returned. Log.Error("Unexpected state {BookingState}/ {LockingState} detected.", selectedBluetoothLockBike.State.Value, selectedBluetoothLockBike.LockInfo.State); return new InvalidState( bikesViewModel, selectedBluetoothLockBike.State.Value, selectedBluetoothLockBike.LockInfo.State, string.Format(AppResources.MarkingBikeInfoErrorStateDisposableClosedDetected, selectedBluetoothLockBike.Description)); case LockingState.Open: case LockingState.Unknown: // Unexepected state detected. /// This state is unexpected because /// - app does not allow to return bike/ cancel reservation when lock is closed /// - as long as app is connected to lock /// - lock can not be opened manually /// - no other device can access lock /// Nevetheless this state is not expected let user either /// - close lock or /// - rent bike /// Log.Error("Unexpected state {BookingState}/ {LockingState} detected.", selectedBluetoothLockBike.State.Value, selectedBluetoothLockBike.LockInfo.State); return new DisposableOpen( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); default: // Do not allow interaction with lock before reserving bike. return new DisposableDisconnected( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); } case Model.State.InUseStateEnum.Reserved: // Bike is reserved, selecte action depending on lock state. switch (selectedBluetoothLockBike.LockInfo.State) { case LockingState.Closed: // Lock could not be opened after reserving bike. return new ReservedClosed( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case LockingState.Disconnected: return new ReservedDisconnected( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case LockingState.Open: // Unwanted state detected. /// This state might occure when a ILOCKIT was manually opened (color code) and app connects afterwards. Log.Error("Unwanted state {BookingState}/ {LockingState} detected.", selectedBluetoothLockBike.State.Value, selectedBluetoothLockBike.LockInfo.State); return new ReservedOpen( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case LockingState.Unknown: // User wants to return bike/ pause ride. return new ReservedUnknown( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); default: // Invalid state detected. Lock must never be open if bike is reserved. throw new ArgumentException(); } case Model.State.InUseStateEnum.Booked: // Bike is booked, selecte action depending on lock state. switch (selectedBluetoothLockBike.LockInfo.State) { case LockingState.Closed: // Ride was paused. return new BookedClosed( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case LockingState.Open: // User wants to return bike/ pause ride. return new BookedOpen( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); case LockingState.Unknown: // User wants to return bike/ pause ride. return new BookedUnknown( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); default: // Invalid state detected. // If bike is booked lock state must be querried before creating view model. return new BookedDisconnected( selectedBluetoothLockBike, isConnectedDelegate, connectorFactory, geolocation, lockService, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser); } default: // Unexpected copri state detected. Log.Error("Unexpected locking {BookingState}/ {LockingState} detected.", selectedBluetoothLockBike.State.Value, selectedBluetoothLockBike.LockInfo.State); return new InvalidState( bikesViewModel, selectedBluetoothLockBike.State.Value, selectedBluetoothLockBike.LockInfo.State, string.Format(AppResources.MarkingBikeInfoErrorStateUnknownDetected, selectedBluetoothLockBike.Description)); } } } }