%

% Copyright 2017-2019 The MathWorks, Inc.
%
% @brief    get default values for unused root inports in sldvData which
%           honor the min-max constraints on them.
% @detail   The min-max is calculated for all root level inports and are
%           returned in the same format as inports in sldvData with three
%           fields: MinMax = a value b/w the min & max; isBusArray = if a
%           certain element in this Data Structure is a bus array;
%           isBusOrStructInfo = if a certain element in this Data Structure
%           is just an information about the BusObject or StructObject
function [status, DefaultsAtUnusedAtInports] = getDefaultValuesForUnusedInports(sldvData)

DefaultsAtUnusedAtInports = [];

modelH = getModelHandle(sldvData);

% get min-max filled for all inports in the sldvData
unUsedSigOnly = true;
[sldvData_corrected, status] = Sldv.DataUtils.addMinMaxToInputs(modelH, sldvData, unUsedSigOnly);

if~status
    return;
end

% get all the root level inports
Inports = sldvData_corrected.AnalysisInformation.InputPortInfo;

% get all the min-max values in the same structural format as Inports
DefaultsAtUnusedAtInports = copyMinMax(Inports);

end

% recursive function to get min-max from the leaf-elements
function minMaxData = copyMinMax(data)

    function acc = visitInports(d)
        if iscell(d)
            acc = cell(size(d));
            for i = 1:numel(d)
                temp = visitInports(d{i});
                acc{i} = temp;
            end
        else
            if isfield(d,'BusObject') || isfield(d,'StructObject')
                acc.MinMax = [];
                if isfield(d,'StructObject')
                    acc.isBusArray = false;
                else
                    acc.isBusArray = (d.Dimensions~=1);
                end
                acc.isBusOrStructInfo = true;
            else
                acc.MinMax = getMinMax(d);
                acc.isBusArray = false;
                acc.isBusOrStructInfo = false;
                noMinMaxDefined = noMinMaxDefined && isempty(acc.MinMax);
                % disp(acc);
            end
        end
    end

    % this flag is used to check if any unused signals had any Min-Max
    % defined on them.
    noMinMaxDefined = true;
    minMaxData = visitInports(data);
    
    % if no min-max was defined by any user on unused signals then return
    % empty data
    if noMinMaxDefined
        minMaxData = [];
    end
end

% get a value b/w min & max
function minMax = getMinMax(data)
minMax = [];
Min = str2double(data.Min);
Max = str2double(data.Max);

if isnan(Min) && isnan(Max)
    return;
end

if isnan(Min)
    minMax = Max;
else
    minMax = Min;
end

if strcmp(data.Complexity, 'complex')
    minMax = complex(minMax, minMax);
end

end

function designModelH = getModelHandle(sldvData)

if isfield(sldvData.ModelInformation,'SubsystemPath')
    [~,extractedmodelName] = fileparts(sldvData.ModelInformation.ExtractedModel);
    modelToRunH = get_param(extractedmodelName,'Handle');
    designModelH = modelToRunH;
else
    designModelH = get_param(sldvData.ModelInformation.Name,'Handle');
end
end
