aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/DataStore/Tango.DataStore.CLI
ModeNameSize
-rw-r--r--App.config2952logstatsplain
-rw-r--r--DataStoreUtil.cs4638logstatsplain
-rw-r--r--DataStoreUtilSettings.cs329logstatsplain
-rw-r--r--Options.cs2679logstatsplain
-rw-r--r--Program.cs1168logstatsplain
d---------Properties43logstatsplain
-rw-r--r--Tango.DataStore.CLI.csproj5846logstatsplain
d---------Web46logstatsplain
-rw-r--r--packages.config444logstatsplain
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Core;
using Tango.Core.Commands;
using Tango.FSE.Common;
using Tango.FSE.Common.FileAssociation;
using Tango.FSE.Common.Navigation;
using Tango.FSE.Procedures.Messages;
using Tango.FSE.Procedures.Navigation;
using Tango.FSE.Procedures.Views;

namespace Tango.FSE.Procedures.ViewModels
{
    public class ProcedureRunnerViewVM : FSEViewModel, IProcedureLogger, INavigationObjectReceiver<RunProcedureNavigationObject>
    {
        public enum RunnerView
        {
            ProcedureRunnerCatalogView,
            ProcedureRunnerExecutionView
        }

        private bool _requiresReloadingOfProjects;
        private bool _isFromNavigation;
        private RunProcedureNavigationObject _navigationObject;

        private RunnerView _selectedView;
        public RunnerView SelectedView
        {
            get { return _selectedView; }
            set { _selectedView = value; RaisePropertyChangedAuto(); }
        }

        private List<PublishedProcedureProject> _publishedProcedureProjects;
        public List<PublishedProcedureProject> PublishedProcedureProjects
        {
            get { return _publishedProcedureProjects; }
            set { _publishedProcedureProjects = value; RaisePropertyChangedAuto(); }
        }

        private ProcedureProject _runningProcedureProject;
        public ProcedureProject RunningProcedureProject
        {
            get { return _runningProcedureProject; }
            set { _runningProcedureProject = value; RaisePropertyChangedAuto(); }
        }

        private ProjectRunner _projectRunner;
        public ProjectRunner ProjectRunner
        {
            get { return _projectRunner; }
            set { _projectRunner = value; RaisePropertyChangedAuto(); }
        }

        private bool _isLoadingProjects;
        public bool IsLoadingProjects
        {
            get { return _isLoadingProjects; }
            set { _isLoadingProjects = value; RaisePropertyChangedAuto(); }
        }

        public bool HasProcedureInputs
        {
            get { return RunningProcedureProject != null && RunningProcedureProject.Inputs.Count > 0; }
        }

        public ResultsViewVM ResultsViewVM { get; set; }

        private String _status;
        public String Status
        {
            get { return _status; }
            set { _status = value; RaisePropertyChangedAuto(); }
        }

        private String _failedError;
        public String FailedError
        {
            get { return _failedError; }
            set { _failedError = value; RaisePropertyChangedAuto(); }
        }

        private bool _isRunning;
        public bool IsRunning
        {
            get { return _isRunning; }
            set { _isRunning = value; RaisePropertyChangedAuto(); }
        }

        private TangoProgress<double> _procedureProgress;
        public TangoProgress<double> ProcedureProgress
        {
            get { return _procedureProgress; }
            set { _procedureProgress = value; RaisePropertyChangedAuto(); }
        }


        public RelayCommand<PublishedProcedureProject> EditProjectCommand { get; set; }
        public RelayCommand<PublishedProcedureProject> RunProjectCommand { get; set; }
        public RelayCommand StartProjectCommand { get; set; }
        public RelayCommand StopProjectCommand { get; set; }

        public ProcedureRunnerViewVM()
        {
            ResultsViewVM = new ResultsViewVM();

            EditProjectCommand = new RelayCommand<PublishedProcedureProject>(EditProject);
            RunProjectCommand = new RelayCommand<PublishedProcedureProject>(RunProject);
            StartProjectCommand = new RelayCommand(StartProject, () => ProjectRunner != null && ProjectRunner.CanRun);
            StopProjectCommand = new RelayCommand(StopProject, () => ProjectRunner != null && ProjectRunner.IsRunning);

            _requiresReloadingOfProjects = true;
            RegisterForMessage<ProcedureProjectPublishedOrSuppressed>((x) => _requiresReloadingOfProjects = true);
        }

        public override void OnApplicationStarted()
        {
            base.OnApplicationStarted();

            FileAssociationProvider.RegisterFileAssociationHandler("procedure", HandlerProcedureFileAssociation);
        }

        private async void StartProject()
        {
            try
            {
                if (IsRunning)
                {
                    await NotificationProvider.ShowError("Cannot execute a procedure while another procedure is running.");
                    return;
                }

                IsRunning = true;
                FailedError = null;
                ResultsViewVM.Results = new List<Result>();
                Status = "Running...";
                var context = new ProcedureContext(RunningProcedureProject, this);
                ProcedureProgress = new TangoProgress<double>(null);
                context.Progress += Context_Progress;
                await ProjectRunner.Run(context);
                Status = "Completed";
                ResultsViewVM.Results = context.Results.ToList();
            }
            catch (OperationCanceledException)
            {
                Status = "Stopped";
            }
            catch (Exception ex)
            {
                Status = "Failed";
                FailedError = ex.FlattenMessage();
            }
            finally
            {
                IsRunning = false;
                ProcedureProgress = new TangoProgress<double>(null, false, 0, 100);
            }
        }

        private void Context_Progress(object sender, TangoProgressChangedEventArgs<double> e)
        {
            ProcedureProgress = e.Progress;
        }

        private void StopProject()
        {
            ProjectRunner.Stop();
        }

        private void EditProject(PublishedProcedureProject project)
        {
            if (project != null)
            {
                NavigationManager.NavigateWithObject<
                    ProceduresModule,
                    ProcedureDesignerView,
                    ProcedureDesignerViewVM.NavigationObject>(
                    new ProcedureDesignerViewVM.NavigationObject()
                    {
                        Project = project
                    });
            }
        }

        public override void OnNavigatedTo()
        {
            base.OnNavigatedTo();

            if (_requiresReloadingOfProjects)
            {
                LoadPublishedProcedureProjects();
            }

            if (_isFromNavigation)
            {
                if (!IsRunning)
                {
                    RunningProcedureProject = _navigationObject.Project;
                    RaisePropertyChanged(nameof(HasProcedureInputs));
                    ProjectRunner = new ProjectRunner(RunningProcedureProject);
                    ProjectRunner.StateChanged += (x, e) => InvalidateRelayCommands();
                    Status = "Ready";
                    InvalidateRelayCommands();
                    SelectedView = RunnerView.ProcedureRunnerExecutionView;

                    if (_navigationObject.StartProcedure)
                    {
                        StartProject();
                    }
                }
                else
                {
                    NotificationProvider.ShowError("Cannot execute a procedure while another procedure is running.");
                }
            }
        }

        private async void LoadPublishedProcedureProjects()
        {
            try
            {
                IsFree = false;
                IsLoadingProjects = true;
                PublishedProcedureProjects = new List<PublishedProcedureProject>();
                PublishedProcedureProjects = await Services.PublishedProcedureProjectsService.GetPublishedProcedureProjects();
                _requiresReloadingOfProjects = false;
                IsFree = true;
            }
            catch (Exception ex)
            {
                IsFree = false;
                LogManager.Log(ex, "Error retrieving published procedure projects.");
                await NotificationProvider.ShowError($"Error occurred while trying to retrieve the procedures collection.\n{ex.FlattenMessage()}");
            }
            finally
            {
                IsLoadingProjects = false;
            }
        }

        private void RunProject(PublishedProcedureProject project)
        {
            RunningProcedureProject = ProcedureProject.FromJson(project.CurrentVersion.ProjectJsonString);
            RaisePropertyChanged(nameof(HasProcedureInputs));
            ProjectRunner = new ProjectRunner(RunningProcedureProject);
            ProjectRunner.StateChanged += (x, e) => InvalidateRelayCommands();
            Status = "Ready";
            InvalidateRelayCommands();
            SelectedView = RunnerView.ProcedureRunnerExecutionView;
        }

        public override Task<bool> OnNavigateBackRequest()
        {
            if (SelectedView == RunnerView.ProcedureRunnerExecutionView && !IsRunning)
            {
                SelectedView = RunnerView.ProcedureRunnerCatalogView;

                if (_isFromNavigation)
                {
                    _isFromNavigation = false;
                    return Task.FromResult(true);
                }

                return Task.FromResult(false);
            }

            _isFromNavigation = false;

            return base.OnNavigateBackRequest();
        }

        public void WriteLine(string text)
        {
            Status = text;
        }

        public void Write(string text)
        {
            Status = text;
        }

        public void Clear()
        {
            //Do nothing
        }

        public void OnNavigatedToWithObject(RunProcedureNavigationObject obj)
        {
            _isFromNavigation = true;
            _navigationObject = obj;
        }

        private async void HandlerProcedureFileAssociation(FileAssociationPackage package)
        {
            if (!CurrentUser.HasPermission(Permissions.FSE_RunProcedureProjectFile))
            {
                await NotificationProvider.ShowError("Current user profile does not allow loading unpublished procedures.");
                return;
            }

            if (File.Exists(package.File))
            {
                try
                {
                    ProcedureProject project = ProcedureProject.FromJson(File.ReadAllText(package.File));
                    LogManager.Log("Loading procedure from file association...");
                    await NavigationManager.NavigateWithObject<ProceduresModule, ProcedureRunnerView, RunProcedureNavigationObject>(new RunProcedureNavigationObject()
                    {
                        Project = project
                    });
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error occurred while trying to handler the procedure file association.");
                }
            }
        }
    }
}