function varargout = setSerialPortPreferences(varargin)
% setSerialPortPreferences Sets the serial port for a given hardware board as
% MATLAB preferences.
%
% setSerialPortPreferences will set the serialport for a given hardware
% board in MATLAB preferences which will be used later by PIL and External
% mode. The function can be invoked in following ways
%
% When the hardware board is a single-core processor, the function takes two
% arguments as char or string in the following order
%           Hardware board
%           Serial port
%
% When the hardware board is a multi-core processor, the function takes three
% arguments as char or string in the following order
%           Hardware board
%           CPU value
%           Serial port
%
% The function returns optional argument known as status which will return
% 1 if the serial port is set successively in MATLAB preferences and
% returns 0 otherwise

% Copyright 2020-2023 The MathWorks, Inc.
%
if nargin == 2
    hardwareBoard = varargin{1};
    CPUValue = '';
    serialPort = varargin{2};
elseif nargin == 3
    hardwareBoard = varargin{1};
    CPUValue = varargin{2};
    serialPort = varargin{3};
elseif (nargin < 2 ||  nargin > 3)
    error(message('TIC2000:codegen:SetSerialPortIncorrectArguments'));
end

status = 0; %#ok<NASGU>

hardwareBoardList = codertarget.tic2000.internal.getSupportedTIC2000Boards;
CPUList = {'CPU1', 'CPU2', 'ARM'};

if isequal(CPUValue,'CPU1CLA1')
   CPUValue = 'CPU1';
elseif isequal(CPUValue,'CPU2CLA1')
   CPUValue = 'CPU2';
end

% Replace co-processor indication in the names  like (C28x), ARM Cortex -
% M4) with empty string
coProcessorPattern = '\(\w*\W*\S*';
hardwareBoardList = strtrim(regexprep(hardwareBoardList, coProcessorPattern, ''));
hardwareBoardFullName = hardwareBoard;
hardwareBoard = strtrim(regexprep(hardwareBoard,  coProcessorPattern,''));

if ~isempty(find(strcmp(hardwareBoardList, hardwareBoard), 1))
    if ~isempty(find(strcmp({'TI Delfino F2837xD', 'TI Delfino F28379D LaunchPad' ...
             'TI F2838x', 'TI F28P65x', 'TI F28P650D LaunchPad'}, hardwareBoardFullName), 1))
        if isempty(find(strcmp(CPUList, CPUValue), 1))
            CPUValue = 'CPU1';
            % For CLA pu, we will be sending the corresponding CPU value in serialport callbacks
			% If incorrect CPU selected throw a warning and select CPU1 as
            % default
            msg = message('TIC2000:codegen:SerialPreferencesIncorrectCPU');
            sldiagviewer.reportWarning(msg.getString,'MessageId',msg.Identifier);
        end
        hardwareBoard = [hardwareBoard ' ' CPUValue];
    elseif contains(hardwareBoardFullName,'ARM')
        hardwareBoard = [hardwareBoard ' ' 'ARM'];
    else
        if ~isempty(CPUValue) && isempty(find(strcmp(CPUList{1}, CPUValue), 1))
            % If wrong CPU selected for single core processors proceed
            % further with a warning
            msg = message('TIC2000:codegen:SerialPreferencesIncorrectCPU');
            sldiagviewer.reportWarning(msg.getString,'MessageId',msg.Identifier);
        end
    end
    hardwareBoard = (strrep(hardwareBoard, ' ', '_'));
    hardwareBoard = (strrep(hardwareBoard, '/', '_'));
    if ischar(serialPort) || isstring(serialPort)
        setpref(hardwareBoard, 'SerialPort', serialPort);
        status = 1;
    else
        error(message('TIC2000:codegen:SetSerialPortIncorrectSerialPort'));
    end
else
    error(message('TIC2000:codegen:SerialPortIncorrectHardwareBoard'));
end

if nargout == 1
    % Provide status output only if variable is used
    varargout{1} = status;
end
end