function [unitArgNorm, unitSIArgNorm, displayInSeconds, formatArg, ...
        scaleFactorArgNorm, baselineObj, varName] = ...
            processReportArgs(lTimerTicksPerSecond, lTimerHWCounterUnit, varargin)
%PROCESSREPORTARGS is used by profiling report and model annotation
% unitArgNorm contains the unit of measurement/time (e.g.: ticks and seconds)
% unitSIArgNorm contains the equivalent of unitArgNorm in the International
% System of Units (if in seconds and scale factor is 1e-3, 1e-6 and 1e-9, it is
% ms, ns and us)

%   Copyright 2010-2019 The MathWorks, Inc.

[varargin{:}] = convertStringsToChars(varargin{:});

p = inputParser;
addParameter(p, 'Units', '', @ischar);
addParameter(p, 'ScaleFactor', '', @ischar);
addParameter(p, 'NumericFormat', '', @ischar);
addParameter(p, 'VariableName', '', @ischar);
addParameter(p, 'Baseline', [], @isobject);
parse(p, varargin{:});

baselineObj = p.Results.Baseline;
varName = p.Results.VariableName;

% Process the units argument
[unitArgNorm, displayInSeconds] = i_processUnitsArg(lTimerTicksPerSecond, ...
                                                     lTimerHWCounterUnit, ...
                                                     p.Results.Units);

if displayInSeconds && isempty(lTimerTicksPerSecond)
    DAStudio.error...
        ('CoderProfile:ExecutionTime:ReportNoTimerTicksPerSecond', ...
        inputname(1))
end

% Process the format argument
formatArg = p.Results.NumericFormat;
formatArg = i_processFormatArg(formatArg, displayInSeconds);

% Process the scale factor argument
scaleFactorArg = p.Results.ScaleFactor;
[scaleFactorArgNorm, scaleFactorArgNormNum] = i_processScaleFactorArg(scaleFactorArg, displayInSeconds);

% Process the International Standard unit
unitSIArgNorm = i_processSIUnit(displayInSeconds, unitArgNorm, scaleFactorArgNorm, scaleFactorArgNormNum);

    
%_______________________________________________________________________________________
function [unitsArgNorm, displayInSeconds] = ...
    i_processUnitsArg(lTimerTicksPerSecond, lTimerHWCounterUnit, unitsArg)
% return the unit of measurement to use in the report - the check order 
% depends on the priority
    
if ~isempty(lTimerHWCounterUnit)
    % non-conventional timer is in use (i.e.: HW counters)
    unitsArgNorm = lTimerHWCounterUnit;
    displayInSeconds = false;
elseif ~isempty(unitsArg)
    % a unit of measurement was passed when the report was opened
    % not possible to use HW counters in this case
    unitsArgNorm = validatestring(unitsArg, {'seconds', 'ticks'});
    displayInSeconds = ~strcmpi(unitsArgNorm, 'ticks');
else
    % no HW counter: choose according to the value of TicksPerSecond
    if ~isempty(lTimerTicksPerSecond) && lTimerTicksPerSecond > 0
        unitsArgNorm = DAStudio.message('CoderProfile:ExecutionTime:ReportUnitsSeconds');
        displayInSeconds = true;
    else
        unitsArgNorm = DAStudio.message('CoderProfile:ExecutionTime:ReportUnitsTimerTicks');
        displayInSeconds = false;
    end
end
        
%_______________________________________________________________________________    
function [scaleFactorArgNormStr, scaleFactorArgNormNum] = i_processScaleFactorArg(scaleFactorArg, displayInSeconds)
% this method returns the scale factor as array of chars (scaleFactorArgNormStr)
% and numeric value (scaleFactorArgNormNum)
scaleFactorArgNormNum = 1;
if displayInSeconds
    if isempty(scaleFactorArg)
        scaleFactorDefault = '1e-9';
        scaleFactorArg = scaleFactorDefault;
    end
    scaleFactorArgNormNum = str2double(scaleFactorArg);
    scaleFactorExponent = log10(scaleFactorArgNormNum);
    if ~isfinite(scaleFactorArgNormNum) || ...
            ~round(scaleFactorExponent)==scaleFactorExponent
        DAStudio.error...
            ('CoderProfile:ExecutionTime:InvalidScaleFactorOptionForReport',...
            scaleFactorArg);
    end
    scaleFactorArgNormStr = sprintf('%1.0g', scaleFactorArgNormNum);
else
    if ~isempty(scaleFactorArg)
        propName = 'ScaleFactor';
        DAStudio.error...
            ('CoderProfile:ExecutionTime:ArgNotValidForTicks',...
            propName);
    else
        scaleFactorArgNormStr = '1';
    end
end
            
%___________________________________________________________________________
function formatArg = i_processFormatArg(formatArg, displayInSeconds)
if displayInSeconds
    validFormat = '^%(([0-9]+\.)?[0-9]+)?[duifeEgG]$';
    if isempty(formatArg)
        if displayInSeconds
            formatArg = '%0.0f';
        else
            formatArg = '%d';
        end
    end
    if isempty(regexp(formatArg, validFormat, 'once'))
        DAStudio.error...
            ('CoderProfile:ExecutionTime:InvalidFormatOptionForReport',...
            formatArg);
    end
else
    if ~isempty(formatArg)
        propName = 'NumericFormat';
        DAStudio.error...
            ('CoderProfile:ExecutionTime:ArgNotValidForTicks',...
            propName);
    else
        formatArg = '%d';
    end
end

%__________________________________________________________________________
function unitsSIStr = i_processSIUnit(displayInSeconds, unitsStr, scaleFactorArgNorm, scaleFactorArgNormNum)

unitsSIStr = [];
if displayInSeconds
    if (scaleFactorArgNormNum == 0) || (scaleFactorArgNormNum == 1)
        % the scaling factor is either not passed/valid or equal to 1
        % use main unit of measurement
        unitsSIStr = [];
    elseif scaleFactorArgNormNum == 1e-3
        unitsSIStr = 'ms';
    elseif scaleFactorArgNormNum == 1e-6
        unitsSIStr = '&micro;s';
    elseif scaleFactorArgNormNum == 1e-9
        unitsSIStr = 'ns';
    else
        % use general format: seconds x scale factor
        unitsSIStr = sprintf('%s &#215; %s', unitsStr, scaleFactorArgNorm);
    end
end
