classdef OptimizeHandler < fxptui.Web.CallbackService.ActionsHandler
    % Class to handle the work for Optimize Callback in FPT.
    
    % Copyright 2019-2020 The MathWorks, Inc.
    
    properties(Constant)
        ActionID = fxptui.internal.ActionFactory.OptimizeID;
    end
    
    methods
        
        function prepare(this, varargin)
            fptInstance = varargin{1};
            workflowSetting = varargin{2};
            clientData = varargin{3};
            
            % update the simulation input with the latest value in base
            % workspace
            model = fptInstance.getModel();
            diagnostic = fxptui.Web.CallbackService.refreshSimulationInput(clientData, model);
            if ~isempty(diagnostic)
                throw(diagnostic);
            end
            
            % get the fxpOptimizationOptions from the WorkflowSetting
            options = workflowSetting.getSettingValue('OptimizationSetting');
            this.parseClientData(clientData, options);
        end
        
        function handleSuccess(this, varargin)
            fptInstance = varargin{1};
            model = fptInstance.getModel();
            
            % g1986173 - switch document view in UI
            dataController = fptInstance.getDataController();
            switchIntent = fxptui.message('setupResultSummary');
            dataController.sendFPTUIDocumentSelection(switchIntent);
            
            % get the Optimzation Result
            dataLayer = fxptds.DataLayerInterface.getInstance();
            workflow = dataLayer.getCurrentWorkflow(model);
            workflowID = workflow.ID;
            result = dataLayer.getResultsByWorkflowID(model, workflowID, 'DataTypeOptimization.OptimizationResult');
            
            if ~isempty(result)
                % generate optimization summary report
                report = this.getSummaryReport(result{1});
                
                % publish report to the client
                resultSummaryController = fptInstance.getResultSummaryController;
                resultSummaryController.publishResultSummary(report);
            end
            
        end
        
        function handleError(this, varargin)
            e = varargin{1};
            fptInstance = varargin{2};
            
            % refresh run browser
            isError = true;
            this.refreshRunBrowser(fptInstance, isError);
            
            % g1986262 - refresh SimulationInputs list on the client
            workflowController = fptInstance.getWorkflowController;
            workflowController.importSimulationInputsFromWorkspace();
            
            % ToDo g2072146: use optimization specific dialog title instead
            fxptui.showdialog('errorTitleFPTGeneralError', e);
        end
        
        function cleanup(~, varargin)
            %no op
        end
        
    end
    
    methods(Hidden)
        
        
        function parseClientData(~, clientData, options)
            parseVal = @FunctionApproximation.internal.Utils.parseCharValue;
            options.AllowableWordLengths = parseVal(clientData.AllowableWordLengths);
            options.MaxIterations = parseVal(clientData.MaxIterations);
            options.MaxTime = parseVal(clientData.MaxTime);
            options.Patience = parseVal(clientData.Patience);
            options.UseParallel = clientData.UseParallel;
            options.ObjectiveFunction = clientData.ObjectiveFunction;
            
            % populate advanced options
            options.AdvancedOptions.PerformNeighborhoodSearch = clientData.PerformNeighborhoodSearch;
            options.AdvancedOptions.SafetyMargin = parseVal(clientData.SafetyMargin);
        end
        
        function report = getSummaryReport(~, result)
            director = fxptui.internal.resultsummary.FPTResultSummaryReportDirector;
            builder = fxptui.internal.resultsummary.optimization.FPTOptimizationReportBuilder;
            director.setBuilder(builder);
            report = director.makeReport(result);
        end
        
    end
end
