using System; using System.Threading.Tasks; using Serilog; using ShareeBike.Services.BluetoothLock; namespace ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command { public static class DisconnectCommand { /// /// Possible steps of connecting or disconnecting a lock. /// public enum Step { DisconnectLock, } /// /// Possible steps of connecting or disconnecting a lock. /// public enum State { GeneralDisconnectError, } /// /// Interface to notify view model about steps/ state changes of connecting or disconnecting lock process. /// public interface IDisconnectCommandListener { /// /// Reports current step. /// /// Current step to report. void ReportStep(Step currentStep); /// /// Reports current state. /// /// Current state to report. /// Message describing the current state. /// Task ReportStateAsync(State currentState, string message); } /// /// Connect or disconnect lock. /// /// /// /// public static async Task InvokeAsync( IBikeInfoMutable bike, ILocksService lockService, IDisconnectCommandListener listener = null) { // Invokes member to notify about step being started. void InvokeCurrentStep(Step step) { if (listener == null) return; try { listener.ReportStep(step); } catch (Exception exception) { Log.ForContext().Error("An exception {@exception} was thrown invoking step-action for step {step} ", exception, step); } } // Invokes member to notify about state change. async Task InvokeCurrentStateAsync(State state, string message) { if (listener == null) return; try { await listener.ReportStateAsync(state, message); } catch (Exception exception) { Log.ForContext().Error("An exception {@exception} was thrown invoking state-action for state {state} ", exception, state); } } // Disconnect lock InvokeCurrentStep(Step.DisconnectLock); if (bike.LockInfo.State != LockingState.UnknownDisconnected) { try { bike.LockInfo.State = await lockService.DisconnectAsync(bike.LockInfo.Id, bike.LockInfo.Guid); Log.ForContext().Information("Lock from bike {bikeId} disconnected successfully.", bike.Id); } catch (Exception exception) { Log.ForContext().Information("Lock from bike {bikeId} can not be disconnected. {@exception}", bike.Id, exception); await InvokeCurrentStateAsync(State.GeneralDisconnectError, exception.Message); } } } } }