function dctSchedulerMessage(levelNum, messageStringOrException, varargin)
; %#ok Undocumented
%DCTSCHEDULERMESSAGE sends a message to the scheduler
%
%  DCTSCHEDULERMESSAGE(LEVEL, EXCEPTION)
%  DCTSCHEDULERMESSAGE(LEVEL, MESSAGE_STRING, EXCEPTION)
%  DCTSCHEDULERMESSAGE(LEVEL, FORMAT_MESSAGE_STRING, A, ...)
%

%  Copyright 2005-2020 The MathWorks, Inc.

if isempty(dctSchedulerMessageHandler)
    return
end

if nargin < 2
    iWarnAndPrintInvalidArgsMessage();
    return
end

if ~iIsValidLogLevel(levelNum)
    % Warn because of bad level
    iWarnAndPrintInvalidArgsMessage();
    % Set level to 0, and attempt to carry on
    levelNum = 0;
end

arg2IsCharOrString = (isstring(messageStringOrException) || ischar(messageStringOrException));

if nargin == 2 && isa(messageStringOrException,'MException')
    errorMessage = messageStringOrException.getReport('extended', 'hyperlinks', 'off');
    iPrintErrorMessage(levelNum, errorMessage);
    return
end

if nargin == 3 && arg2IsCharOrString && isa(varargin{1},'MException')
    errorMessage = sprintf('%s\n%s', messageStringOrException, varargin{1}.getReport('extended', 'hyperlinks', 'off'));
    iPrintErrorMessage(levelNum, errorMessage);
    return
end

if nargin >= 2 && arg2IsCharOrString
    % NB: don't bother converting varargin - sprintf will return char providing
    % the format string is char.
    errorMessage = convertStringsToChars(messageStringOrException);
    iPrintErrorMessage(levelNum, errorMessage, varargin{:})
    return
end

iWarnAndPrintInvalidArgsMessage();

end


function iWarnAndPrintInvalidArgsMessage()
    warning(message('parallel:cluster:DctSchedulerMessageInvalidInputs')); 
    errorMessage = 'WARNING - The inputs to dctSchedulerMessage must be an integer value and a string, character vector or MException.';
    iPrintErrorMessage(0, errorMessage);
end


function iPrintErrorMessage(levelNum, errorMessage, varargin)

    % Only sprintf if we have to, otherwise the base string can't have e.g.
    % backslashes
    if nargin > 2
        try
            errorMessage = sprintf(errorMessage, varargin{:});
        catch err
            % Use unformatted messageString if sprintf fails
            warning(message('parallel:cluster:DctSchedulerMessageBadFormatString', err.message));
        end
    end

    try 
        dctSchedulerMessageHandler(errorMessage, levelNum);
    catch err %#ok<NASGU>
        % Do Nothing - It's OK
    end
end


function valid = iIsValidLogLevel(value)
    % Check that the log level is a 1x1 integer.
    valid = (isnumeric(value) &&  (numel(value) == 1) ...
        && (uint16(value) == value));
end
