using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; using Tango.Core.Commands; using Tango.Core.IO; using Tango.FSE.BL; using Tango.FSE.Common; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.RemoteUpgrade; using Tango.FSE.Upgrade.Views; using static Tango.FSE.Upgrade.ViewModels.ApplicationUpgradeGeneratedViewVM; namespace Tango.FSE.Upgrade.ViewModels { public class ApplicationUpgradeGeneratedViewVM : RemoteUpgradeViewModel, INavigationObjectReceiver { public class NavigationObject { public TangoVersion SelectedVersion { get; set; } public Machine SelectedMachine { get; set; } public bool UpgradeNow { get; set; } public TemporaryFile TemporaryTupFile { get; set; } } private String _tupFileLocation; public String TupFileLocation { get { return _tupFileLocation; } set { _tupFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private TemporaryFile _temporaryTupFile; public TemporaryFile TemporaryTupFile { get { return _temporaryTupFile; } set { _temporaryTupFile = value; InvalidateRelayCommands(); } } private bool _canUpgradeNow; public bool CanUpgradeNow { get { return _canUpgradeNow; } set { _canUpgradeNow = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private String _canUpgradeNowError; public String CanUpgradeNowError { get { return _canUpgradeNowError; } set { _canUpgradeNowError = value; RaisePropertyChangedAuto(); } } private bool _isUpgradeNow; public bool IsUpgradeNow { get { return _isUpgradeNow; } set { _isUpgradeNow = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private bool _isUpgradeNowSelected; public bool IsUpgradeNowSelected { get { return _isUpgradeNowSelected; } set { _isUpgradeNowSelected = value; RaisePropertyChangedAuto(); } } private TangoVersion _selectedVersion; public TangoVersion SelectedVersion { get { return _selectedVersion; } set { _selectedVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private Machine _selectedMachine; public Machine SelectedMachine { get { return _selectedMachine; } set { _selectedMachine = value; RaisePropertyChangedAuto(); } } private RemoteUpgradeHandler _handler; public RemoteUpgradeHandler Handler { get { return _handler; } set { _handler = value; RaisePropertyChangedAuto(); } } private bool _isCompleted; public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private bool _suppressFirmwareUpgrade; public bool SuppressFirmwareUpgrade { get { return _suppressFirmwareUpgrade; } set { _suppressFirmwareUpgrade = value; RaisePropertyChangedAuto(); } } public RelayCommand StartUpgradeCommand { get; set; } public RelayCommand SaveTupFileCommand { get; set; } public RelayCommand SelectTupFileLocationCommand { get; set; } public ApplicationUpgradeGeneratedViewVM() { Handler = new RemoteUpgradeHandler("Ready"); StartUpgradeCommand = new RelayCommand(StartUpgrade, () => CanUpgradeNow && Handler.Status != RemoteUpgradeHandlerStatus.Completed); SaveTupFileCommand = new RelayCommand(SaveTupFile, () => TupFileLocation != null); SelectTupFileLocationCommand = new RelayCommand(SelectTupFileLocation, () => SelectedVersion != null && SelectedMachine != null); } public override void OnApplicationStarted() { base.OnApplicationStarted(); MachineProvider.MachineConnected += (_, __) => InvalidateCanUpgradeNow(); MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); } private async void SelectTupFileLocation() { String fileName = $"{SelectedMachine.SerialNumber}_Update_{DateTime.Now.Date.ToFileName()}_v{SelectedVersion.Version}.tup"; var result = await StorageProvider.SaveFile("Select update package location", "Tango Update Package|*.tup", fileName, ".tup"); if (result) { TupFileLocation = result.SelectedItem; } } private void InvalidateCanUpgradeNow() { CanUpgradeNowError = null; //if (!IsUpgradeNowSelected) return; if (SelectedMachine == null) { CanUpgradeNow = false; IsUpgradeNowSelected = false; CanUpgradeNowError = "Target machine not specified."; return; } if (!MachineProvider.IsConnected) { CanUpgradeNow = false; IsUpgradeNowSelected = false; CanUpgradeNowError = "The selected machine is not currently connected."; return; } if (MachineProvider.Machine.Guid != SelectedMachine.Guid) { CanUpgradeNow = false; IsUpgradeNowSelected = false; CanUpgradeNowError = "The selected machine is different from the one currently connected."; return; } if (!MachineProvider.ConnectionType.IsRemote()) { CanUpgradeNow = false; IsUpgradeNowSelected = false; CanUpgradeNowError = "The current machine connection type does not support remote upgrade."; return; } CanUpgradeNow = true; } private async void StartUpgrade() { try { IsFree = false; Handler = await RemoteUpgradeManager.PerformRemoteApplicationUpgrade(TemporaryTupFile, !SuppressFirmwareUpgrade); await Handler.WaitForCompletion(); IsCompleted = true; await MachineProvider.DisconnectAndWaitForReconnection(TimeSpan.FromSeconds(20), TimeSpan.FromMinutes(1), "The remote machine is now performing final upgrade operations."); } catch (OperationCanceledException) { //Aborted... } catch (AuthorizationException ex) { await NotificationProvider.ShowError(ex.Message); } catch (Exception ex) { LogManager.Log(ex, "Error occurred while executing remote application upgrade."); } finally { await TemporaryTupFile.DeleteAsync(); IsFree = true; InvalidateRelayCommands(); } } private async void SaveTupFile() { try { File.Copy(TemporaryTupFile, TupFileLocation, true); TemporaryTupFile.Delete(); IsCompleted = true; await NotificationProvider.ShowSuccess("Application upgrade package saved successfully."); await ModularNavigationManager.NavigateBack(); } catch (Exception ex) { LogManager.Log(ex, "Error copying temporary tup file to selected location."); await NotificationProvider.ShowError($"Error occurred while trying to save the application package file.\n{ex.FlattenMessage()}"); } } public void OnNavigatedToWithObject(NavigationObject obj) { SelectedVersion = obj.SelectedVersion; SelectedMachine = obj.SelectedMachine; IsUpgradeNow = obj.UpgradeNow; IsUpgradeNowSelected = IsUpgradeNow; TemporaryTupFile = obj.TemporaryTupFile; InvalidateCanUpgradeNow(); InvalidateRelayCommands(); } public override void OnBeforeNavigatedTo() { base.OnBeforeNavigatedTo(); Handler = new RemoteUpgradeHandler("Ready"); IsCompleted = false; SelectedVersion = null; SelectedMachine = null; IsUpgradeNow = false; IsUpgradeNowSelected = false; TemporaryTupFile = null; InvalidateRelayCommands(); } public async override Task OnNavigateBackRequest() { if (!IsCompleted) { var abort = await NotificationProvider.ShowWarningQuestion("Are you sure you want to abort the upgrade operation?"); if (Handler.Status == RemoteUpgradeHandlerStatus.Started) { if (Handler.CanAbort) { Handler.Abort(); } else { await NotificationProvider.ShowWarning("Cannot abort the operation at this stage."); return false; } } return abort; } return true; } } }