classdef (Sealed, Hidden) ClassHelpers
    %CLASSHELPERS Class containing static helper methods regarding the 
    %target data model classes that make up the target framework.

%   Copyright 2018-2020 The MathWorks, Inc.
    
    methods (Static)
        
        function classes = getPublishedTargetClasses()
            
            classes = {'AddOn', ...
                'Alias', ...
                'API', ...
                'APIImplementation', ...
                'Board', ...
                'BuildDependencies', ...
                'Command', ...
                'CommunicationChannel', ...
                'CommunicationInterface', ...
                'CommunicationProtocolStack', ...
                'ConnectionProperties', ...
                'Function', ...
                'HostOperatingSystemSupport', ...
                'HostProcessExecutionTool', ...
                'LanguageImplementation', ...
                'MainFunction', ...
                'PILProtocol', ...
                'Port', ...
                'Processor', ...
                'RS232Channel', ...
                'SystemCommandExecutionTool', ...
                'TCPChannel', ...
                'TargetConnection', ...
                'Timer', ...
                'Tools', ...
                'UDPChannel'};
        end
        
        function identifiers = getClassIdentifiers(className)
            
            classObjects = target.get(className);
            identifiers = {classObjects.Id};
        end
        
        function name = getFullyQualifiedName(className)
            name = "target." + string(className);
        end
        
        function value = isequalImplementation(varargin)
            
            emptyValues = cellfun(@isempty, varargin);
            if any(emptyValues)
                % If any element is empty, check if they all are, and if they
                % are all of the same type.
                value = all(emptyValues) && cellfun(@(x) isa(x, class(varargin{1})), varargin(2:end));
            else
                % Loop over all inputs and stop as soon as two are
                % different.
                i = 1;
                stop = nargin;
                while i < stop && varargin{i}.equalTo(varargin{i+1})
                    i = i + 1;
                end
                value = (i == stop);
            end
        end
        
        function value = getAddOnProperty(extensibleInstance, propertyName)
    
            % Get property
            addOnProperty = extensibleInstance.getAddOnProperty(propertyName);

            if isempty(addOnProperty)    
                error(message('targetframework:Data:NoPropertyFound', propertyName, extensibleInstance.StaticMetaClass.mcosName, extensibleInstance.Id));
            else
                value = addOnProperty.Value;
            end
        end        
        
        function setAddOnProperty(extensibleInstance, propertyName, value)
    
            % Get property
            addOnProperty = extensibleInstance.getAddOnProperty(propertyName);

            if isempty(addOnProperty)    
                error(message('targetframework:Data:NoPropertyFound', propertyName, extensibleInstance.StaticMetaClass.mcosName, extensibleInstance.Id));
            else
                addOnProperty.Value = value;
            end
        end
        
        function settableProperties = getClassSettableProperties(className)
            
            fullyQualifiedClassName = target.internal.ClassHelpers.getFullyQualifiedName(className);
            classMetaData = meta.class.fromName(fullyQualifiedClassName);
            settablePropertyIndices = strcmp({classMetaData.PropertyList.SetAccess}, 'public') & ~[classMetaData.PropertyList.Hidden];
            settableProperties = {classMetaData.PropertyList(settablePropertyIndices).Name};
        end
        
        function options = getCreateOptions(className, name)
            arguments
                className (1, 1) string
                % We need to allow also non-scalar strings as when using
                % repeating tuples in functionSignatures.json, all the
                % first arguments of the tuple (the names in this case) are
                % passed to the "choices" function, i.e., this function.
                name (1, :) string
            end
            
            if strcmp(name(end), "Copy")
                options = target.internal.ClassHelpers.getClassIdentifiers(className);
            else
                options = "";
            end
        end
        
    end
end

% LocalWords:  TCP
