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.BL.Enumerations; using Tango.Core.Commands; using Tango.FSE.BL; using Tango.FSE.Common; using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.RemoteUpgrade; using Tango.FSE.Upgrade.Views; using static Tango.FSE.Upgrade.ViewModels.FirmwareUpgradeGeneratedViewVM; namespace Tango.FSE.Upgrade.ViewModels { public class FirmwareUpgradeGeneratedViewVM : RemoteUpgradeViewModel, INavigationObjectReceiver { public class NavigationObject { public TangoVersion SelectedVersion { get; set; } public String TfpFileLocation { get; set; } public bool IsExistingTfpFile { get; set; } } private bool _isUsingExistingTfp; public bool IsUsingExistingTfp { get { return _isUsingExistingTfp; } set { _isUsingExistingTfp = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private String _tfpFileLocation; public String TfpFileLocation { get { return _tfpFileLocation; } set { _tfpFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private String _tfpFileLocationToSave; public String TfpFileLocationToSave { get { return _tfpFileLocationToSave; } set { _tfpFileLocationToSave = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private TangoVersion _selectedVersion; public TangoVersion SelectedVersion { get { return _selectedVersion; } set { _selectedVersion = value; RaisePropertyChangedAuto(); 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 _isUpgradeNowSelected; public bool IsUpgradeNowSelected { get { return _isUpgradeNowSelected; } set { _isUpgradeNowSelected = 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(); } } public RelayCommand StartUpgradeCommand { get; set; } public RelayCommand SaveTfpFileCommand { get; set; } public RelayCommand SelectTfpFileLocationCommand { get; set; } public FirmwareUpgradeGeneratedViewVM() { Handler = new RemoteUpgradeHandler("Ready"); StartUpgradeCommand = new RelayCommand(StartUpgrade, () => CanUpgradeNow && Handler.Status != RemoteUpgradeHandlerStatus.Completed); SaveTfpFileCommand = new RelayCommand(SaveTfpFile, () => TfpFileLocationToSave != null && !IsUsingExistingTfp); SelectTfpFileLocationCommand = new RelayCommand(SelectTfpFileLocation, () => SelectedVersion != null); } public override void OnApplicationStarted() { base.OnApplicationStarted(); MachineProvider.MachineConnected += (_, __) => InvalidateCanUpgradeNow(); MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); FileAssociationProvider.RegisterFileAssociationHandler("tfp", HandleTfpFileAssociation); } private void InvalidateCanUpgradeNow() { CanUpgradeNowError = null; if (!MachineProvider.IsConnected) { CanUpgradeNow = false; IsUpgradeNowSelected = false; CanUpgradeNowError = "No active machine connection detected for remote upgrade."; 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 SaveTfpFile() { try { File.Copy(TfpFileLocation, TfpFileLocationToSave, true); try { File.Delete(TfpFileLocation); } catch { } IsCompleted = true; await NotificationProvider.ShowSuccess("Firmware upgrade package saved successfully."); await ModularNavigationManager.NavigateBack(); } catch (Exception ex) { LogManager.Log(ex, "Error copying temporary tfp file to selected location."); await NotificationProvider.ShowError($"Error occurred while trying to save the firmware package file.\n{ex.FlattenMessage()}"); } } private async void StartUpgrade() { try { IsFree = false; Handler = await RemoteUpgradeManager.PerformRemoteFirmwareUpgrade(TfpFileLocation); 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 firmware upgrade."); } finally { if (!IsUsingExistingTfp) { try { File.Delete(TfpFileLocation); } catch { } } IsFree = true; InvalidateRelayCommands(); } } private async void SelectTfpFileLocation() { String fileName = $"firmware_package_v{SelectedVersion.FirmwareVersion}.tfp"; var result = await StorageProvider.SaveFile("Select firmware package location", "Tango Firmware Package|*.tfp", fileName, ".tfp"); if (result) { TfpFileLocationToSave = result.SelectedItem; } } public override void OnBeforeNavigatedTo() { base.OnBeforeNavigatedTo(); Handler = new RemoteUpgradeHandler("Ready"); IsCompleted = false; SelectedVersion = null; IsUpgradeNowSelected = true; InvalidateRelayCommands(); } public void OnNavigatedToWithObject(FirmwareUpgradeGeneratedViewVM.NavigationObject obj) { SelectedVersion = obj.SelectedVersion; TfpFileLocation = obj.TfpFileLocation; IsUsingExistingTfp = obj.IsExistingTfpFile; InvalidateCanUpgradeNow(); } 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; } private void HandleTfpFileAssociation(FileAssociationPackage package) { if (!IsFree) { NotificationProvider.ShowError("Cannot perform firmware upgrade while another upgrade is running."); return; } if (!CurrentUser.HasPermission(Permissions.FSE_RemoteUpgradeOnline)) { NotificationProvider.ShowError("Current user profile does not allow online remote upgrade."); return; } if (File.Exists(package.File)) { try { LogManager.Log("Performing remote firmware upgrade from file association..."); Handler = new RemoteUpgradeHandler("Ready"); IsCompleted = false; TfpFileLocation = package.File; IsUsingExistingTfp = true; InvalidateCanUpgradeNow(); NavigationManager.NavigateTo(true); ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.FirmwareUpgradeGeneratedView); } catch (Exception ex) { LogManager.Log(ex, "Error occurred while trying to handle the tfp file association."); } } } } }