using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Serilog;
using TINK.Model.Connector.Updater;
using TINK.Model.Device;
using TINK.Model.User.Account;
using TINK.Repository;
using TINK.Repository.Request;
using TINK.Repository.Response;
namespace TINK.Model.Connector
{
public class Command : Base, ICommand
{
/// True if connector has access to copri server, false if cached values are used.
public bool IsConnected => CopriServer.IsConnected;
/// No user is logged in.
public string SessionCookie => null;
/// Is raised whenever login state has changed.
public event LoginStateChangedEventHandler LoginStateChanged;
/// Constructs a copri query object.
/// Server which implements communication.
public Command(
ICopriServerBase p_oCopriServer) : base(p_oCopriServer)
{
}
///
/// Logs user in.
/// If log in succeeds either and session might be updated if it was no more valid (logged in by an different device).
/// If log in fails (password modified) session cookie is set to empty.
/// If communication fails an exception is thrown.
///
public async Task DoLogin(
string mail,
string password,
string deviceId)
{
if (string.IsNullOrEmpty(mail))
{
throw new ArgumentNullException("Can not login user. Mail address must not be null or empty.");
}
if (string.IsNullOrEmpty(password))
{
throw new ArgumentNullException("Can not login user. Password must not be null or empty.");
}
if (string.IsNullOrEmpty(deviceId))
{
throw new ArgumentNullException("Can not login user. Device not be null or empty.");
}
AuthorizationResponse response;
try
{
response = (await CopriServer.DoAuthorizationAsync(mail, password, deviceId)).GetIsResponseOk(mail);
}
catch (Exception)
{
throw;
}
var l_oAccount = response.GetAccount(MerchantId, mail, password);
// Log in state changes. Notify parent object to update.
LoginStateChanged?.Invoke(this, new LoginStateChangedEventArgs(l_oAccount.SessionCookie, l_oAccount.Mail));
return l_oAccount;
}
/// Logs user out.
public async Task DoLogout()
{
Log.ForContext().Error("Unexpected log out request detected. No user logged in.");
await Task.CompletedTask;
}
///
/// Request to reserve a bike.
///
/// Bike to book.
public async Task DoReserve(
Bikes.BikeInfoNS.BC.IBikeInfoMutable bike)
{
Log.ForContext().Error("Unexpected booking request detected. No user logged in.");
await Task.CompletedTask;
}
/// Request to cancel a reservation.
/// Bike to book.
public async Task DoCancelReservation(Bikes.BikeInfoNS.BC.IBikeInfoMutable bike)
{
Log.ForContext().Error("Unexpected cancel reservation request detected. No user logged in.");
await Task.CompletedTask;
}
/// Get authentication keys.
/// Bike to book.
public async Task CalculateAuthKeys(Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable bike)
{
Log.ForContext().Error("Unexpected request to get authentication keys detected. No user logged in.");
await Task.CompletedTask;
}
/// Updates COPRI lock state for a booked bike.
/// Bike to update locking state for.
/// Location where lock was opened/ changed.
/// Response on updating locking state.
public async Task StartReturningBike(Bikes.BikeInfoNS.BC.IBikeInfoMutable bike)
{
Log.ForContext().Error("Unexpected request to notify about start of returning bike. No user logged in.");
await Task.CompletedTask;
}
/// Notifies COPRI about start of returning sequence.
/// Operator specific call.
/// Bike to return.
/// Response on notification about start of returning sequence.
public async Task UpdateLockingStateAsync(Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable bike, LocationDto location)
{
Log.ForContext().Error("Unexpected request to update locking state detected. No user logged in.");
await Task.CompletedTask;
}
public async Task DoBookAsync(Bikes.BikeInfoNS.BC.IBikeInfoMutable bike, LockingAction? nextAction = null)
{
Log.ForContext().Error("Unexpected booking request detected. No user logged in.");
await Task.CompletedTask;
}
public async Task BookAndOpenAync(Bikes.BikeInfoNS.CopriLock.IBikeInfoMutable bike)
{
Log.ForContext().Error("Unexpected request to book and open bike detected. No user logged in.");
await Task.CompletedTask;
}
public async Task DoReturn(
Bikes.BikeInfoNS.BC.IBikeInfoMutable bike,
LocationDto location,
ISmartDevice smartDevice)
{
Log.ForContext().Error("Unexpected returning request detected. No user logged in.");
return await Task.FromResult(new BookingFinishedModel());
}
public async Task ReturnAndCloseAsync(
Bikes.BikeInfoNS.CopriLock.IBikeInfoMutable bike,
ISmartDevice smartDevice)
{
Log.ForContext().Error("Unexpected close lock and return request detected. No user logged in.");
return await Task.FromResult(new BookingFinishedModel());
}
///
/// Submits feedback to copri server.
///
/// Feedback to submit.
#if USCSHARP9
public async Task DoSubmitFeedback(ICommand.IUserFeedback userFeedback, Uri opertorUri)
#else
public async Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri)
#endif
{
Log.ForContext().Error("Unexpected submit feedback request detected. No user logged in.");
await Task.CompletedTask;
}
/// Submits mini survey to copri server.
/// Collection of answers.
public async Task DoSubmitMiniSurvey(IDictionary answers)
{
Log.ForContext().Error("Unexpected submit mini survey request detected. No user logged in.");
await Task.CompletedTask;
}
public Task OpenLockAsync(Bikes.BikeInfoNS.CopriLock.IBikeInfoMutable bike)
=> throw new NotImplementedException();
public Task CloseLockAsync(Bikes.BikeInfoNS.CopriLock.IBikeInfoMutable bike)
=> throw new NotImplementedException();
}
}