classdef ActionFactory
    % ACTIONFACTORY factory for grouping of actions

    %   Copyright 2019-2021 The MathWorks, Inc.

    properties(Constant)
        ApplyID               = "apply"
        CollectID             = "collect"
        ExploreOptimizationID = "exploreOptimization"
        NullID                = "null"
        OptimizeID            = "optimize"
        StopOptimizeID        = "stopOptimize"
        ResumeOptimizeID      = "resumeOptimize"
        PrepareID             = "prepare"
        ProposeID             = "propose"
        VerifyID              = "verify"
        CompareID             = "compare"
        ExportID             = "export"
    end

    methods

        function actions = getActions(this, intent)
            % given an intent, create an array of all the actions needed
            % for the given intent

            switch intent
                case 'Collection'
                    actions = [ ...
                        fxptui.internal.action.SetCollectionRunNameAction, ...             % CollectID
                        fxptui.internal.action.SetVerificationRunNameAction, ...           % CollectID
                        fxptui.internal.action.CollectAction, ...                          % CollectID
                        fxptui.internal.action.UpdateContainerAction, ...                  % CollectID
                        fxptui.internal.action.SetVerificationRunNameAction, ...           % VerifyID
                        fxptui.internal.action.VerifyAction, ...                           % VerifyID
                        fxptui.internal.action.UpdateContainerAction, ...                  % VerifyID
                        fxptui.internal.action.UpdateVerificationResultBaselineAction, ... % VerifyID
                        fxptui.internal.action.AddVerificationResultAction, ...            % VerifyID
                        fxptui.internal.action.CompareVerificationResultAction             % CompareID
                        ];
                    actionIDs = [ ...
                        this.CollectID, this.CollectID, this.CollectID, this.CollectID, ...
                        this.VerifyID, this.VerifyID, this.VerifyID, this.VerifyID, this.VerifyID, ...
                        this.CompareID ...
                        ];

                case 'OptimizedConversion'
                    if fixed.internal.utility.featuremanager.FeatureManager.getStatus('fxpoptStopInFPT')
                        actions = [ ...
                            fxptui.internal.action.PrepareAction, ...                          % PrepareID
                            fxptui.internal.action.RegisterPrepareAction, ...                  % PrepareID
                            fxptui.internal.action.UpdateSimulationScenariosAction, ...        % OptimizeID
                            fxptui.internal.action.RegisterOptimizeAction, ...                 % OptimizeID
                            fxptui.internal.action.SetupOptimizationDetailsAction, ...         % OptimizeID
                            fxptui.internal.action.UpdateRunBrowserAction, ...                 % OptimizeID
                            fxptui.internal.action.OptimizeAction, ...                         % OptimizeID
                            fxptui.internal.action.RegisterOptimizeAction, ...                 % OptimizeID
                            fxptui.internal.action.UpdateOptimizeDataAction, ...               % OptimizeID
                            fxptui.internal.action.UpdateRunBrowserAction, ...                 % OptimizeID
                            fxptui.internal.action.StopOptimizeAction, ...                     % StopOptimizeID
                            fxptui.internal.action.ResumeOptimizeAction, ...                   % ResumeOptimizeID
                            fxptui.internal.action.ApplyOptimizationSolutionAction, ...        % ApplyID
                            fxptui.internal.action.RegisterApplyOptimizationSolutionAction, ...% ApplyID
                            fxptui.internal.action.CompareOptimizationResultAction, ...        % ExploreOptimizationID
                            ];
                        actionIDs = [ ...
                            this.PrepareID, this.PrepareID, ...
                            this.OptimizeID, this.OptimizeID, this.OptimizeID, ...
                            this.OptimizeID, this.OptimizeID, this.OptimizeID, ...
                            this.OptimizeID, this.OptimizeID,...
                            this.StopOptimizeID, ...
                            this.ResumeOptimizeID, ...
                            this.ApplyID, this.ApplyID, ...
                            this.ExploreOptimizationID ...
                            ];
                    else
                        actions = [ ...
                            fxptui.internal.action.PrepareAction, ...                          % PrepareID
                            fxptui.internal.action.RegisterPrepareAction, ...                  % PrepareID
                            fxptui.internal.action.UpdateSimulationScenariosAction, ...        % OptimizeID
                            fxptui.internal.action.OptimizeAction, ...                         % OptimizeID
                            fxptui.internal.action.RegisterOptimizeAction, ...                 % OptimizeID
                            fxptui.internal.action.UpdateRunBrowserAction, ...                 % OptimizeID
                            fxptui.internal.action.StopOptimizeAction, ...                     % StopOptimizeID
                            fxptui.internal.action.ApplyOptimizationSolutionAction, ...        % ApplyID
                            fxptui.internal.action.RegisterApplyOptimizationSolutionAction, ...% ApplyID
                            fxptui.internal.action.CompareOptimizationResultAction, ...        % ExploreOptimizationID
                            ];
                        actionIDs = [ ...
                            this.PrepareID, this.PrepareID, ...
                            this.OptimizeID, this.OptimizeID, this.OptimizeID, this.OptimizeID ...
                            this.StopOptimizeID, ...
                            this.ApplyID, this.ApplyID, ...
                            this.ExploreOptimizationID ...
                            ];
                    end
                case 'IterativeConversion'
                    actions = [ ...
                        fxptui.internal.action.PrepareAction, ...                  % PrepareID
                        fxptui.internal.action.RegisterPrepareAction, ...          % PrepareID
                        fxptui.internal.action.SetCollectionRunNameAction, ...     % CollectID
                        fxptui.internal.action.SetVerificationRunNameAction, ...   % CollectID
                        fxptui.internal.action.CollectAction, ...                  % CollectID
                        fxptui.internal.action.UpdateContainerAction, ...          % CollectID
                        fxptui.internal.action.ProposeAction, ...                  % ProposeID
                        fxptui.internal.action.RegisterProposeAction, ...          % ProposeID
                        fxptui.internal.action.ApplyAction, ...                    % ApplyID
                        fxptui.internal.action.RegisterApplyAction, ...            % ApplyID
                        fxptui.internal.action.VerifyAction, ...                   % VerifyID
                        fxptui.internal.action.UpdateContainerAction, ...          % VerifyID
                        fxptui.internal.action.AddVerificationResultAction, ...    % VerifyID
                        fxptui.internal.action.CompareVerificationResultAction ... % CompareID
                        ];
                    actionIDs = [ ...
                        this.PrepareID, this.PrepareID, ...
                        this.CollectID, this.CollectID, this.CollectID, this.CollectID, ...
                        this.ProposeID, this.ProposeID, ...
                        this.ApplyID, this.ApplyID, ...
                        this.VerifyID, this.VerifyID, this.VerifyID, ...
                        this.CompareID ...
                        ];
                otherwise
                    actions = fxptui.internal.action.NullAction;
                    actionIDs = this.NullID;
            end

            % get the strategies need to read the values from the settings
            getterStrategy = fxptui.internal.workflowsetting.SettingValueGetterStrategyFactory.getStrategy(intent);
            setterStrategy = fxptui.internal.workflowsetting.SettingValueSetterStrategyFactory.getStrategy(intent);

            % assign the ID to each action
            for idx = 1:numel(actions)
                action = actions(idx);
                actionID = actionIDs(idx);
                action.setID(actionID);
                action.setSettingValueGetterStrategy(getterStrategy);
                action.setSettingValueSetterStrategy(setterStrategy);
            end
        end

        function detectors = getConflictDetectors(this, intent)
            % given an intent, create an array of all the actions needed
            % for the given intent
            % interpretation of the conflict detector is if something is
            % detected it is a conflict
            % ex. if you detect InvalidModel, that's a problem
            % ex. if you are attempting to verify a baseline but
            % not(BaselineCollection), that's a problem

            switch intent
                case 'Collection'
                    detectors = [ ...
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % CollectID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % VerifyID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % CompareID
                        fxptds.internal.workflow.conflictdetector.VerificationResultDetector, ...      % CollectID - once you verify, you can not collect
                        fxptds.internal.workflow.conflictdetector.BaselineCollectionDetector, ...      % CollectID - once you collect, you can not collect again
                        not(fxptds.internal.workflow.conflictdetector.BaselineCollectionDetector), ... % VerifyID - you must have done collect to verify
                        not(fxptds.internal.workflow.conflictdetector.VerificationResultDetector), ... % CompareID - you must have a VerificationResult to Compare
                        ];
                    actionIDs = [ ...
                        this.CollectID, ...
                        this.VerifyID, ...
                        this.CompareID ...
                        this.CollectID, ...
                        this.CollectID, ...
                        this.VerifyID, ...
                        this.CompareID ...
                        ];
                    messageIDs = [ ...
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % VerificationResultDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % BaselineCollectionDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(BaselineCollectionDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(VerificationResultDetector)
                        ];
                case 'OptimizedConversion'
                    detectors = [ ...
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % PrepareID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ...  % OptimizeID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % ExploreOptimizationID
                        fxptds.internal.workflow.conflictdetector.OptimizationResultDetector, ...      % PrepareID - once you optimize, you can not prepare
                        not(fxptds.internal.workflow.conflictdetector.OptimizationValidSolutionDetector), ...      % OptimizeID - you must have a valid solution to resume optimization
                        not(fxptds.internal.workflow.conflictdetector.OptimizationResultDetector), ... % ApplyID - you must optimize to apply
                        not(fxptds.internal.workflow.conflictdetector.OptimizationValidSolutionDetector), ... % ApplyID - you must have a valid solution to apply
                        not(fxptds.internal.workflow.conflictdetector.OptimizationResultDetector), ... % ExploreOptimizationID - you must optimize to compare
                        not(fxptds.internal.workflow.conflictdetector.OptimizationValidSolutionDetector), ... % ExploreOptimizationID - you must have a valid solution to compare
                        not(fxptds.internal.workflow.conflictdetector.OptimizationResultSignalDetector), ... % ExploreOptimizationID - you must have a valid SDI signal to compare
                        not(fxptds.internal.workflow.conflictdetector.OptimizationResultDetector), ...      % ExportID - you must optimize to export
                        ];
                    actionIDs = [ ...
                        this.PrepareID, ...
                        this.OptimizeID, ...
                        this.ExploreOptimizationID, ...
                        this.PrepareID, ...
                        this.OptimizeID, ...
                        this.ApplyID, ...
                        this.ApplyID, ...
                        this.ExploreOptimizationID, ...
                        this.ExploreOptimizationID, ...
                        this.ExploreOptimizationID, ...
                        this.ExportID, ...
                        ];
                    messageIDs = [ ...
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % OptimizationResultDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(OptimizationValidSolutionDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(OptimizationResultDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(OptimizationValidSolutionDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(OptimizationResultDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(OptimizationValidSolutionDetector)
                        "FixedPointTool:fixedPointTool:msgNotPlottableDiffSDI", ... % not(OptimizationResultSignalDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % OptimizationResultDetector
                        ];
                case 'IterativeConversion'
                    detectors = [ ...
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % PrepareID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % CollectID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % ProposeID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % ApplyID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % VerifyID
                        fxptds.internal.workflow.conflictdetector.InvalidModelDetector, ... % CompareID
                        fxptds.internal.workflow.conflictdetector.BaselineCollectionDetector, ... % PrepareID - once you collect baseline, you can not propose
                        fxptds.internal.workflow.conflictdetector.BaselineCollectionDetector, ... % CollectID - once you collect, you can not collect again
                        not(fxptds.internal.workflow.conflictdetector.BaselineCollectionDetector), ... % ProposeID - you must collect to propose
                        not(fxptds.internal.workflow.conflictdetector.IterativeProposeRegisteredDetector), ... % ApplyID - you must propose to apply
                        fxptds.internal.workflow.conflictdetector.AllProposedDataTypesAcceptedDetector, ... % ApplyID - your propose run must have proposal to apply
                        not(fxptds.internal.workflow.conflictdetector.IterativeApplyRegisteredDetector), ... % VerifyID - you must propose to apply
                        not(fxptds.internal.workflow.conflictdetector.VerificationResultDetector), ... % CompareID - you must have a VerificationResult to Compare
                        ];
                    actionIDs = [ ...
                        this.PrepareID, ...
                        this.CollectID, ...
                        this.ProposeID, ...
                        this.ApplyID, ...
                        this.VerifyID, ...
                        this.CompareID, ...
                        this.PrepareID, ...
                        this.CollectID, ...
                        this.ProposeID, ...
                        this.ApplyID, ...
                        this.ApplyID, ...
                        this.VerifyID, ...
                        this.CompareID, ...
                        ];
                    messageIDs = [ ...
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "", ... % InvalidModelDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % BaselineCollectionDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % BaselineCollectionDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(BaselineCollectionDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(IterativeProposeRegisteredDetector)
                        "FixedPointTool:fixedPointTool:msgNotAcceptChecked", ... % AllProposedDataTypesAcceptedDetector
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(IterativeApplyRegisteredDetector)
                        "FixedPointTool:fixedPointTool:msgFPTGeneralError", ... % not(VerificationResultDetector)
                        ];
                otherwise
                    detectors = fxptds.internal.workflow.conflictdetector.NullConflictDetector;
                    actionIDs = this.NullID;
                    messageIDs = "";
            end

            % assign the ID to each action
            for idx = 1:numel(detectors)
                detector = detectors(idx);

                % set the action ID
                actionID = actionIDs(idx);
                detector.setID(actionID);

                % set the message ID
                messageID = messageIDs(idx);
                detector.setMessageID(messageID);

            end
        end

    end

end

% LocalWords:  FPT fxpopt
