% Generic - Scheduler Component for Generic Schedulers
 
%   Copyright 2011-2023 The MathWorks, Inc.

% TODO:doc properties
% NB This class is hidden for now as the Profiles API is not yet documented
classdef (Hidden) Generic < parallel.settings.schedulerComponent.ThirdPartyCJS
    properties (PCTGetSet, Transient, PCTConstraint = 'enum:parallel.internal.types.OperatingSystem')
        OperatingSystem
    end
    properties (PCTGetSet, Transient, PCTConstraint = 'logicalscalar')
        HasSharedFilesystem
    end
    properties (PCTGetSet, Transient, PCTConstraint = 'string')
        PluginScriptsLocation
    end
    properties (PCTGetSet, Transient, PCTConstraint = 'additionalproperties')
        AdditionalProperties
    end
    properties (Hidden, Dependent, Transient, PCTConstraint = 'string')
        IntegrationScriptsLocation
    end
    methods
        function set.IntegrationScriptsLocation( obj, val )
            obj.PluginScriptsLocation = val;
        end
        function value = get.IntegrationScriptsLocation( obj )
            value = obj.PluginScriptsLocation;
        end
    end
    
    methods (Hidden, Static) % Implementation of NamedNode Hidden, Static methods
        function obj = hBuildFromSettings(name, settingsNode, parentSettingsNode, varargin)
            import parallel.internal.types.SchedulerType
            obj = parallel.settings.schedulerComponent.Generic( ...
                name, SchedulerType.Generic, settingsNode, parentSettingsNode, varargin{:});
        end
    end

    methods (Access = protected)
        function obj = Generic(name, typeEnum, node, parentNode, varargin)
            obj@parallel.settings.schedulerComponent.ThirdPartyCJS( ...
                name, typeEnum, node, parentNode, varargin{:});
        end

        function tf = isEquivalentAdditionalProperties(obj, otherAPs)
            % Need to be careful when comparing AdditionalProperties because we
            % need to treat the DefaultValue in settings and an unspecified
            % value passed in as each being valid, empty AdditionalProperties.
            if isempty(otherAPs)
                % Not specified, equivalent to empty
                otherAPs = struct();
            end
            if isa(obj.AdditionalProperties, "parallel.cluster.AdditionalProperties")
                ourAPs = obj.AdditionalProperties.getAsStruct();
            else
                % Using default value, equivalent to empty
                ourAPs = struct();
            end
            tf = isequal(ourAPs, otherAPs);
        end

        function tf = isAlreadyDiscovered(obj, names, values)

            % PCT_JT_UI (g2803057): structs only need to be serialised for use
            % in DiscoverClusterWizardController.
            try
                values = parallel.internal.discover.Generic.deserialiseStructProperties(names, values);
            catch err
                % Can get here if this fcn isn't being called by the discovery
                % framework so the struct properties haven't been serialised. In
                % that case, ignore the error. Otherwise rethrow it.
                if err.identifier ~= "MATLAB:json:ExpectedValue"
                    rethrow(err)
                end
            end

            % Defer to parent class for common 3P CJS properties
            tf = isAlreadyDiscovered@parallel.settings.schedulerComponent.ThirdPartyCJS(obj, names, values);
            if ~tf
                return
            end

            % Compare properties specific to Generic (just AdditionalProperties)
            otherAPs = obj.extractValuesFromNamesValues('AdditionalProperties', names, values);
            tf = obj.isEquivalentAdditionalProperties(otherAPs);
        end
    end

    methods (Hidden) % overrides of CustomPropDisp
       function [n, f] = hCustomizeDisplay(obj, level)
            n = {'OperatingSystem', 'HasSharedFilesystem', ...
                'PluginScriptsLocation', 'AdditionalProperties'};
            if nargin < 2
                f = obj.get(n);
            else
                f = cellfun(@(x) obj.get(x, level), n, 'UniformOutput', false);
            end
       end
    end
end
