classdef AnalyzerDataManager < handle
    % ANALYZERDATAMANAGER collects data from backend and
    % packages it for the UI using REPORTDIRECTOR and REPORTUTILS
    
    % Copyright 2018-2019 The MathWorks, Inc.
    
    properties (SetAccess = private, GetAccess = public)
        RunType
        AdvisorReport
        ReportUtilsDatabase
        ReportUtils
        ReportBuilder
        ReportDirector
    end
    
    methods   
        %% Setters for advisor report and run type 
        function setAdvisorReport(this, report)
            this.AdvisorReport = report; 
        end
        
        function setRunType(this, runType)
            this.RunType = runType;
        end
        
        function uiReport = getAnalyzerResults(obj, selectedSystem, runType, topModel)
            %% Collects the advisor results and generates UI report
            
            % Initialize the UI report
            uiReport = {};
            
            % Store runType 
            obj.RunType = runType;
            
            % Collect advisor results, report if there is any unexpected error
            try    
                obj.AdvisorReport = DataTypeWorkflow.Advisor.runChecks(selectedSystem, obj.RunType, topModel);
                obj.registerPrepare(topModel)
                
                uiReport = obj.createUIReport();                
            catch
                % Reset the advisor report 
                obj.AdvisorReport = {};
                
                % Show generic error in FPT UI
                fxptui.showdialog('genericerror');
            end    
            
        end
        
        function registerPrepare(obj, topModel)
            
            % get data layer instance
            dataLayer = fxptds.DataLayerInterface.getInstance();
            
            % register the intent to prepare with Analyzer in DesignStore
            facade = dataLayer.getWorkflowTopologyFacade(topModel);
            context = fxptds.WorkflowTopology.WorkflowContextFactory.getContext(fxptds.UserIntent.PrepareModel, ...
                'TopModel', topModel, 'Settings', obj.RunType, 'Results', obj.AdvisorReport);
            facade.register(context);
        end
        
        function uiReport = createUIReport(obj)
            % Setup report building infrastructure
            obj.setupReportInfrastructure();            

            % Generate UI report using ReportDirector
            uiReport = obj.ReportDirector.makeReport(obj.ReportUtils);
            
            % Add selected SUD details to uiReport
            uiReport = obj.addSUDInfo(uiReport);
        end
        
        function uiReport = addSUDInfo(obj, uiReport)
            sudInfo = struct;
            sudInfo.Name = obj.AdvisorReport.SetupInfo.entry;
            [sudInfo.UniqueID, sudInfo.ObjectClass] = fxptds.Utils.getIDClass(sudInfo.Name);            
            uiReport.SUDInfo = sudInfo;
        end
        
        function setupReportInfrastructure(obj)
            %% Setup report building infrastructure          
            
            % Initialize report building infrastructure objects
            reportInfrastructure = obj.InitializeReportInfrastructure();
            
            % Setup ReportUtilsDatabase 
            obj.ReportUtilsDatabase = obj.setupReportUtilsDatabase(reportInfrastructure.reportUtilsDatabase);

            % Setup ReportUtils
            obj.ReportUtils = obj.setupReportUtils(reportInfrastructure.reportUtils, reportInfrastructure.reportUtilsDatabase);
            
            % Setup ReportDirector 
            obj.ReportDirector = obj.setupReportDirector(reportInfrastructure.reportDirector, reportInfrastructure.reportBuilder);
            
            % Setup ReportBuilder
            obj.ReportBuilder = reportInfrastructure.reportBuilder;
        end 
        
        function reportInfrastructure = InitializeReportInfrastructure(~)
            % output struct initialization
            reportInfrastructure = struct;            
            
            % create a report database
            reportInfrastructure.reportUtilsDatabase = DataTypeWorkflow.Advisor.internal.utils.ReportUtilsDatabase;
            
            % create a report utils
            reportInfrastructure.reportUtils = DataTypeWorkflow.Advisor.internal.utils.ReportUtils;
            
            % create a report builder
            reportInfrastructure.reportBuilder = DataTypeWorkflow.Advisor.internal.utils.ReportBuilder;  
            
            % create a report director
            reportInfrastructure.reportDirector = DataTypeWorkflow.Advisor.internal.utils.ReportDirector;
        end    
        
        function reportUtilsDatabase = setupReportUtilsDatabase(obj, reportUtilsDatabase)
            %% Setup ReportUtilsDatabase for the advisor report
            
            % parse the report of the selected type
            reportUtilsDatabase.parseReport(obj.AdvisorReport, obj.RunType);         
        end
        
        function reportUtils = setupReportUtils(~, reportUtils, reportUtilsDatabase)
            %% Setup ReportUtils for the advisor report
            
            % set the report db
            reportUtils.ReportDB = reportUtilsDatabase;
            
            % register the report
            reportUtils.register();
        end
        
        function reportDirector = setupReportDirector(~, reportDirector, reportBuilder)
            %% Setup ReportDirector to generate the report
            
            % set the report builder
            reportDirector.setBuilder(reportBuilder);
        end
    end
end

% LocalWords:  nofixptlicenseanalyzer
