function mode_out = featureOn(feature, mode_in)
%

% Copyright 2014-2023 The MathWorks, Inc.

mlock;
persistent features;

if isempty(features)
    features = struct(...
        'coderassumptions', true, ...
        'DisableSubnormalsForSIL', 0, ...
        'XcpTargetConnection', true, ...
        'XcpCoderTarget', true, ...
        'XcpDeferredStreaming', false, ...
        'XcpBigEndian', true, ...
        'ExtModeTargetFramework', true, ...
        'XcpPackedMode', true, ...
        'CoderAssumptionsTestMode', coder.internal.connectivity.CATestModes.TestModeDisabled, ...
        'CoderAssumptionsEmitReport', false, ...
        'UseMF0CodeDescriptor', true, ...
        'SILMemoryCheckTool', false, ...
        'SupportImageType', true, ...
        'PSTestCodeInstrumentation', false, ...
        'BusLogging', true, ...
        'BufferedFileWriter', false, ...
        'OpenCodeView', true, ...
        'SILPILAtomicSubsystem', true, ...
        'DSMForAtomicSubsystem', false, ...
        'ATSLogging', true, ...
        'CondSubSystemsLogging', false, ...
        'TargetFrameworkSIL', true, ...
        'ATSFunctionCall', true, ...
        'AUTOSARExportFuncSubsysSIL', true, ...
        'ERTExportFuncSubsysSIL', false, ...
        'ParameterService', false, ...
        'ChildLogging', true);
end

% Check for outputs
if nargout == 1
    if isfield(features, feature)
        mode_out = features.(feature);
    else
        mode_out = getOrSetSLFeature(feature);
    end
end

% Check for inputs
if nargin >= 2
    
    % Verify type before continuing
    switch feature
        case 'CoderAssumptionsTestMode'
            % new value must be 'CATestModes'
            assert(isa(mode_in, 'coder.internal.connectivity.CATestModes'), ...
                'Feature value for ''CoderAssumptionsTestMode'' must be a coder.internal.connectivity.CATestModes!');
        case 'DisableSubnormalsForSIL'
            % new value must numerical between 0 and 2
            assert((isnumeric(mode_in) && mode_in >=0 && mode_in < 3),...
                'Feature value for ''%s'' must be a numerical between 0 and 2!', feature)
        otherwise
            % new value must be boolean
            assert(islogical(mode_in) || ~isfield(features, feature),...
                'Feature value for ''%s'' must be a logical if not an SLFeature!', feature)
    end
    if isfield(features, feature)
        % Assign new value to struct field.
        features.(feature) = mode_in;
    else
        getOrSetSLFeature(feature, mode_in);
    end
    
end

end

function varargout = getOrSetSLFeature(feature, varargin)
% Deal with get/set for slfeature features
if nargin == 1
    varargout{1} = 0;
end
if exist('slfeature', 'builtin') ~= 5
    % slfeature may not exist if this is MATLAB Coder XIL
    % and Simulink happens to not be installed
    return;
end
if nargin == 2
    slfeature(feature, varargin{1});
else
    varargout{1} = slfeature(feature);
end
end
