classdef DeriveStrategy < fxptds.WorkflowTopology.Strategy
    %% DERIVESTRATEGY class
    % Handles the Collect Ranges action in FPT when Derive Ranges is
    % selected as the collection method
    
    % Copyright 2018-2019 The MathWorks, Inc.
    
    % Access is protected and extended to Facade and to the test class
    methods (Access = {?fxptds.WorkflowTopology.Strategy, ?fxptds.WorkflowTopology.Facade, ?WorkflowTopologyTestCase})
        function execute(this)
            
            % declare the target node Name (unique key)
            rootName = this.TopModel;
            targetName = this.FPTRunID;
            
            % starting at the root, find the most recent design that has
            % been created whether it be the root or an design created
            query = this.createDefaultQuery();
            query.Type = "Design";
            query.Limit = 1;
            
            % execute the query and extract value from cell array
            extractedData = this.executeQuery(rootName, query);
            sourceName = this.processQueryData(extractedData);
            
            % get the SDI ID's from a simulation of the same ID so it can
            % be merged into the DeriveAction node
            if this.Store.doesNodeExist(targetName)
                collectNode = this.Store.getNodeObject(targetName);
                collectNode.toggleIsDerive();
                
                % if the node Name has already been declared in the Store,
                % invalidate all Actions that succeed the target node
                % ex. A user derives ranges to run name Run1 and then proposes
                % data types for that run. The user then simulates using the
                % same run name Run1. The original DeriveAction and Proposal
                % from that derive should be invalidated
                nodesToInvalidate = this.getNodesToInvalidate(targetName);
                % nodesToInvalidate is an array of node names to invalidate
                this.invalidateNodes(nodesToInvalidate);
                
            else
                % create a new DeriveAction Node
                type = fxptds.WorkflowTopology.element.NodeType.DeriveAction;
                this.createAndAddNodeByType(type);
                
                % connect the Simulate Action to the Root design
                this.Store.connect(sourceName, targetName);
            end
            
        end
        
    end
    
    methods (Access = {?fxptds.WorkflowTopology.Strategy, ?WorkflowTopologyTestCase})
        function nodesToInvalidate = getNodesToInvalidate(this, nodeName)
            % call super to get the workflow branch
            nodesToInvalidate = getNodesToInvalidate@fxptds.WorkflowTopology.Strategy(this, nodeName);
            % remove the initial node
            nodesToInvalidate = setdiff(nodesToInvalidate, nodeName);
        end
        
    end
    
end

