2023-04-05 15:02:10 +02:00
|
|
|
using System;
|
2022-08-30 15:42:25 +02:00
|
|
|
using Serilog;
|
2024-04-09 12:53:23 +02:00
|
|
|
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
|
|
|
using ShareeBike.Model.Connector;
|
|
|
|
using ShareeBike.Model.Device;
|
|
|
|
using ShareeBike.Model.User;
|
|
|
|
using ShareeBike.MultilingualResources;
|
|
|
|
using ShareeBike.Services.BluetoothLock;
|
|
|
|
using ShareeBike.Services.Geolocation;
|
|
|
|
using ShareeBike.View;
|
|
|
|
using ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
|
|
|
|
|
|
|
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock
|
2021-05-13 20:03:07 +02:00
|
|
|
{
|
2022-09-06 16:08:19 +02:00
|
|
|
public static class RequestHandlerFactory
|
|
|
|
{
|
|
|
|
/// <summary> Creates a request handler.</summary>
|
|
|
|
/// <param name="selectedBike"></param>
|
|
|
|
/// <param name="isConnectedDelegate"></param>
|
|
|
|
/// <param name="connectorFactory"></param>
|
2023-04-05 15:02:10 +02:00
|
|
|
/// <param name="geolocation"></param>
|
2022-09-06 16:08:19 +02:00
|
|
|
/// <param name="viewUpdateManager"></param>
|
|
|
|
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
|
|
|
/// <param name="viewService"></param>
|
|
|
|
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
2023-08-31 12:20:06 +02:00
|
|
|
/// <param name="context">Specifies the context (last action performed).</param>
|
2022-09-06 16:08:19 +02:00
|
|
|
/// <returns>Request handler.</returns>
|
|
|
|
public static IRequestHandler Create(
|
|
|
|
Model.Bikes.BikeInfoNS.BC.IBikeInfoMutable selectedBike,
|
|
|
|
Func<bool> isConnectedDelegate,
|
|
|
|
Func<bool, IConnector> connectorFactory,
|
2023-04-05 15:02:10 +02:00
|
|
|
IGeolocationService geolocation,
|
2022-09-06 16:08:19 +02:00
|
|
|
ILocksService lockService,
|
|
|
|
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
|
|
|
ISmartDevice smartDevice,
|
|
|
|
IViewService viewService,
|
|
|
|
IBikesViewModel bikesViewModel,
|
|
|
|
IUser activeUser)
|
|
|
|
{
|
2023-04-05 15:02:10 +02:00
|
|
|
if (!(selectedBike is IBikeInfoMutable selectedBluetoothLockBike))
|
2022-09-06 16:08:19 +02:00
|
|
|
return null;
|
|
|
|
|
|
|
|
switch (selectedBluetoothLockBike.State.Value)
|
|
|
|
{
|
|
|
|
case Model.State.InUseStateEnum.Disposable:
|
|
|
|
|
2023-04-19 12:14:14 +02:00
|
|
|
// Bike is reserved, select action depending on lock state.
|
2022-09-06 16:08:19 +02:00
|
|
|
switch (selectedBluetoothLockBike.LockInfo.State)
|
|
|
|
{
|
|
|
|
case LockingState.Open:
|
|
|
|
case LockingState.UnknownFromHardwareError:
|
2023-04-19 12:14:14 +02:00
|
|
|
// Unexpected state detected.
|
2022-09-06 16:08:19 +02:00
|
|
|
/// 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
|
2023-04-19 12:14:14 +02:00
|
|
|
/// Nevertheless this state is not expected let user either
|
2022-09-06 16:08:19 +02:00
|
|
|
/// - close lock or
|
|
|
|
/// - rent bike
|
|
|
|
/// </remarks>
|
|
|
|
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);
|
|
|
|
|
2024-04-09 12:53:23 +02:00
|
|
|
case LockingState.Closed:
|
|
|
|
case LockingState.UnknownDisconnected:
|
2022-09-06 16:08:19 +02:00
|
|
|
// Do not allow interaction with lock before reserving bike.
|
|
|
|
return new DisposableDisconnected(
|
|
|
|
selectedBluetoothLockBike,
|
|
|
|
isConnectedDelegate,
|
|
|
|
connectorFactory,
|
|
|
|
geolocation,
|
|
|
|
lockService,
|
|
|
|
viewUpdateManager,
|
|
|
|
smartDevice,
|
|
|
|
viewService,
|
|
|
|
bikesViewModel,
|
|
|
|
activeUser);
|
2024-04-09 12:53:23 +02:00
|
|
|
|
|
|
|
default:
|
|
|
|
// Invalid state detected. Lock must never be open if bike is reserved.
|
|
|
|
throw new ArgumentException();
|
2022-09-06 16:08:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
case Model.State.InUseStateEnum.Reserved:
|
|
|
|
|
2023-04-19 12:14:14 +02:00
|
|
|
// Bike is reserved, select action depending on lock state.
|
2022-09-06 16:08:19 +02:00
|
|
|
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.UnknownDisconnected:
|
|
|
|
return new ReservedDisconnected(
|
|
|
|
selectedBluetoothLockBike,
|
|
|
|
isConnectedDelegate,
|
|
|
|
connectorFactory,
|
|
|
|
geolocation,
|
|
|
|
lockService,
|
|
|
|
viewUpdateManager,
|
|
|
|
smartDevice,
|
|
|
|
viewService,
|
|
|
|
bikesViewModel,
|
|
|
|
activeUser);
|
|
|
|
|
|
|
|
case LockingState.Open:
|
|
|
|
// Unwanted state detected.
|
2023-04-19 12:14:14 +02:00
|
|
|
/// This state might occur when a ILOCKIT was manually opened (color code) and app connects afterwards.
|
2022-09-06 16:08:19 +02:00
|
|
|
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.UnknownFromHardwareError:
|
|
|
|
// 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:
|
|
|
|
|
2023-04-19 12:14:14 +02:00
|
|
|
// Bike is booked, select action depending on lock state.
|
2022-09-06 16:08:19 +02:00
|
|
|
switch (selectedBluetoothLockBike.LockInfo.State)
|
|
|
|
{
|
|
|
|
case LockingState.Closed:
|
2023-08-31 12:20:06 +02:00
|
|
|
// User wants to close lock.
|
2022-09-06 16:08:19 +02:00
|
|
|
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.UnknownFromHardwareError:
|
|
|
|
// User wants to return bike/ pause ride.
|
|
|
|
return new BookedUnknown(
|
|
|
|
selectedBluetoothLockBike,
|
|
|
|
isConnectedDelegate,
|
|
|
|
connectorFactory,
|
|
|
|
geolocation,
|
|
|
|
lockService,
|
|
|
|
viewUpdateManager,
|
|
|
|
smartDevice,
|
|
|
|
viewService,
|
|
|
|
bikesViewModel,
|
|
|
|
activeUser);
|
|
|
|
|
2024-04-09 12:53:23 +02:00
|
|
|
case LockingState.UnknownDisconnected:
|
2022-09-06 16:08:19 +02:00
|
|
|
// Invalid state detected.
|
2023-04-19 12:14:14 +02:00
|
|
|
// If bike is booked lock state must be queried before creating view model.
|
2022-09-06 16:08:19 +02:00
|
|
|
return new BookedDisconnected(
|
|
|
|
selectedBluetoothLockBike,
|
|
|
|
isConnectedDelegate,
|
|
|
|
connectorFactory,
|
|
|
|
geolocation,
|
|
|
|
lockService,
|
|
|
|
viewUpdateManager,
|
|
|
|
smartDevice,
|
|
|
|
viewService,
|
|
|
|
bikesViewModel,
|
|
|
|
activeUser);
|
2024-04-09 12:53:23 +02:00
|
|
|
|
|
|
|
default:
|
|
|
|
// Invalid state detected. Lock must never be open if bike is reserved.
|
|
|
|
throw new ArgumentException();
|
2022-09-06 16:08:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-05-13 20:03:07 +02:00
|
|
|
}
|