using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.Core.DI;
using Tango.Core.ExtensionMethods;
using Tango.Integration.ExternalBridge;
using Tango.PMR.Integration;
using Tango.PPC.Common;
using Tango.PPC.Common.ExternalBridge;
using Tango.PPC.Common.Navigation;
using Tango.PPC.UI.Dialogs;
namespace Tango.PPC.UI.ViewModels
{
/// <summary>
/// Represents the external bridge view ViewModel.
/// </summary>
/// <seealso cref="Tango.PPC.Common.PPCViewModel" />
[TangoCreateWhenRegistered]
public class ExternalBridgeViewVM : PPCViewModel
{
private bool _disconnecting;
private const int KEEP_SAFETY_AUTHENTICATION_MINUTES = 5;
#region Properties
private ExternalBridgeClientConnectedEventArgs _connection;
/// <summary>
/// Gets or sets the last client connection event arguments.
/// </summary>
public ExternalBridgeClientConnectedEventArgs Connection
{
get { return _connection; }
set { _connection = value; RaisePropertyChangedAuto(); }
}
private User _user;
/// <summary>
/// Gets or sets the user connected user.
/// </summary>
public User User
{
get { return _user; }
set { _user = value; RaisePropertyChangedAuto(); }
}
#endregion
#region Commands
/// <summary>
/// Gets or sets the close session command.
/// </summary>
public RelayCommand CloseSessionCommand { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ExternalBridgeViewVM"/> class.
/// </summary>
public ExternalBridgeViewVM()
{
CloseSessionCommand = new RelayCommand(CloseSession, () => !_disconnecting);
}
#endregion
#region Private Methods
/// <summary>
/// Closes the current session.
/// </summary>
private void CloseSession()
{
LogManager.Log("Disconnecting current external bridge session.");
_disconnecting = true;
InvalidateRelayCommands();
ExternalBridgeService.DisconnectFullControlSession();
}
#endregion
#region Override Methods
/// <summary>
/// Called when the navigation system has navigated to this VM view.
/// </summary>
public override void OnNavigatedTo()
{
base.OnNavigatedTo();
_disconnecting = false;
InvalidateRelayCommands();
}
/// <summary>
/// Called when the application has been started.
/// </summary>
public override void OnApplicationStarted()
{
ExternalBridgeService.ConnectionRequest += ExternalBridgeService_ConnectionRequest;
ExternalBridgeService.FullControlSessionDisconnected += ExternalBridgeService_FullControlSessionDisconnected;
}
#endregion
#region Event Handlers
/// <summary>
/// Handles the <see cref="ExternalBridgeService.FullControlSessionDisconnected"/> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void ExternalBridgeService_FullControlSessionDisconnected(object sender, EventArgs e)
{
if (IsVisible)
{
LogManager.Log("External bridge client disconnected. Navigating to home module...");
InvokeUI(() =>
{
NavigationManager.NavigateTo(NavigationView.HomeModule);
});
}
}
/// <summary>
/// Handles the <see cref="ExternalBridgeService.ConnectionRequest"/> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="ExternalBridgeClientConnectedEventArgs"/> instance containing the event data.</param>
private async void ExternalBridgeService_ConnectionRequest(object sender, ExternalBridgeClientConnectedEventArgs e)
{
LogManager.Log($"External bridge connection request received.\n{e.ToJsonString()}");
if (!e.Request.Intent.RequiresPassword() || e.Request.Password == Settings.ExternalBridgePassword)
{
e.ApplicationInformation.Version = ApplicationManager.VersionAndTag;
e.ApplicationInformation.StartupDate = ApplicationManager.StartUpDate.ToUniversalTime().ToString();
Connection = e;
User = Adapter.Users.SingleOrDefault(x => x.Guid == e.Request.UserGuid);
if (User != null)
{
LogManager.Log($"External bridge connection user has been identified as {User.Contact.FullName}");
}
if (e.Request.RequireSafetyLevelOperations)
{
DateTime lastAuthenticationTime;
bool bypassSafetyConfirmation = false;
if (ExternalBridgeReceiver.LastSafetyLevelContactsTimes.TryGetValue(e.Request.UserName, out lastAuthenticationTime))
{
if (DateTime.Now < lastAuthenticationTime.AddMinutes(KEEP_SAFETY_AUTHENTICATION_MINUTES))
{
bypassSafetyConfirmation = true;
e.Confirm();
}
}
if (!bypassSafetyConfirmation)
{
SafetyLevelOperationsConfirmationViewVM vm = new SafetyLevelOperationsConfirmationViewVM(e);
await NotificationProvider.ShowDialog(vm);
if (vm.DialogResult)
{
e.Confirm();
}
else
{
e.Decline("Safety level connection refused by the remote user.");
return;
}
}
}
else
{
e.Confirm();
}
if (e.Request.Intent == ExternalBridgeLoginIntent.FullControl)
{
LogManager.Log("Navigating to external bridge view...");
InvokeUI(() =>
{
NavigationManager.NavigateTo(NavigationView.ExternalBridgeView, false);
});
}
}
else
{
e.Decline("Connection password did not match the machine external bridge password.");
LogManager.Log("Connection password did not match the machine external bridge password.");
}
}
#endregion
}
}