using System; using System.Threading.Tasks; using TINK.Model.Connector; using TINK.Repository.Request; using TINK.Services.BluetoothLock; using TINK.Services.Geolocation; using TINK.ViewModel; using static TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand; using static TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command.GetLockedLocationCommand; namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock { public class BikeInfoMutable : BC.BikeInfoMutable, IBikeInfoMutable { /// Provides a connector object. private Func ConnectorFactory { get; } /// Provides geolocation information. private IGeolocationService GeolocationService { get; } /// Provides a connector object. private ILocksService LockService { get; } /// Delegate to retrieve connected state. private Func IsConnectedDelegate { get; } /// Object to manage update of view model objects from Copri. protected Func ViewUpdateManager { get; } /// Constructs a bike object from source. /// Manages update of view model objects from Copri. public BikeInfoMutable( IGeolocationService geolocation, ILocksService lockService, Func isConnectedDelegate, Func connectorFactory, Func viewUpdateManager, BikeInfo bike, string stationName) : base( bike != null ? bike.Bike : throw new ArgumentNullException(nameof(bike)), bike.Drive, bike.DataSource, bike.IsDemo, bike.Group, bike.StationId, stationName, bike.OperatorUri, bike.TariffDescription, () => DateTime.Now, bike.State) { LockInfo = new LockInfoMutable( bike.LockInfo.Id, bike.LockInfo.Guid, bike.LockInfo.UserKey, bike.LockInfo.AdminKey, bike.LockInfo.Seed, bike.LockInfo.State); GeolocationService = geolocation ?? throw new ArgumentException($"Can not instantiate {nameof(BikeInfoMutable)}- object. No geolocation object available."); LockService = lockService ?? throw new ArgumentException($"Can not instantiate {nameof(BikeInfoMutable)}- object. No lock service object available."); IsConnectedDelegate = isConnectedDelegate ?? throw new ArgumentException($"Can not instantiate {nameof(BikeInfoMutable)}- object. No is connected delegate available."); ConnectorFactory = connectorFactory ?? throw new ArgumentException($"Can not instantiate {nameof(BikeInfoMutable)}- object. No connector available."); ViewUpdateManager = viewUpdateManager ?? throw new ArgumentException($"Can not instantiate {nameof(BikeInfoMutable)}- object. No update manger available."); } public LockInfoMutable LockInfo { get; } ILockInfoMutable IBikeInfoMutable.LockInfo => LockInfo; /// /// Closes the lock and updates copri. /// /// View model to process closing notifications. /// Task which stops polling. public async Task CloseLockAsync( ICloseCommandListener listener, Task stopPollingTask) { await InvokeAsync( this, GeolocationService, LockService, IsConnectedDelegate, ConnectorFactory, listener, stopPollingTask); } /// /// Gets the location of the locked bike. /// /// View model to process notifications. /// public async Task GetLockedBikeLocationAsync(IGetLockedLocationCommandListener listener) => await InvokeAsync( this, GeolocationService, LockService, listener: listener); public override string ToString() { return $"Id={Id}{(TypeOfBike != null ? $";type={TypeOfBike}" : "")};state={State.ToString()};Lock id={LockInfo.Id}"; } } }