function msgPortNames = containsArrayOfBuses(modelH)
%

% Copyright 2010-2020 The MathWorks, Inc.

    if modelH ~= bdroot(modelH)
        % Model needs to be compiled for subsystem
        assert(~strcmp(get_param(bdroot(modelH), 'SimulationStatus'), 'stopped'))
    end

    ssInBlkHs = Sldv.utils.getSubSystemPortBlks(modelH);
    numInports = length(ssInBlkHs);
    msgPortNames = {};
    dataAccessor = Simulink.data.DataAccessor.create(get_param(bdroot(modelH), 'name'));
    for idx=1:numInports
        [isBus, dataType] = Sldv.utils.isInOutportBlkDataTypeBus(ssInBlkHs(idx));
        if isBus
            if modelH == bdroot(modelH)
                % Root inports
                dims = str2num(get_param(ssInBlkHs(idx), 'PortDimensions'));   % 'PortDimensions' may be -1. But it is ok as we check for prod(dims) > 1
                                                                               % Also, do not replace 'str2num' with 'str2double' as 'PortDimensions' may be a list
            else
                % Subsystem inports
                ph = get_param(ssInBlkHs(idx), 'PortHandles');
                dims = get(ph.Outport(1), 'CompiledPortDimensions');
            end

            if prod(dims) > 1
                % Port is a bus array
                msgPortNames{end+1} = getString(message('Sldv:utils:containsArrayOfBuses:BusWithTypeDim', getfullname(ssInBlkHs(idx)), ['''' strtrim(strrep(dataType, 'Bus:', '')) ''''], num2str(dims))); %#ok<AGROW>
            else
                % Port is a bus. Check if any sub-bus is an array
                busObj = Sldv.utils.getBusObjectFromName(dataType, true, dataAccessor);
                [subBusDim, errMsg] = checkSubBusDims(busObj, dataAccessor);
                if prod(subBusDim) > 1
                    msgPortNames{end+1} = getString(message('Sldv:utils:containsArrayOfBuses:BusWithDim', getfullname(ssInBlkHs(idx)), errMsg, num2str(subBusDim))); %#ok<AGROW>
                end
            end
        end
    end
end

function [subBusDim, errMsg] = checkSubBusDims(busObject, dataAccessor)
    subBusDim = -1;
    errMsg = '';
    for i=1:length(busObject.Elements)
        [isBus, subBusObj] = Sldv.utils.isBusType(busObject.Elements(i).DataType, dataAccessor);
        if isBus
            if prod(busObject.Elements(i).Dimensions) > 1
                subBusDim = busObject.Elements(i).Dimensions;
                errMsg = ['''' strtrim(strrep(busObject.Elements(i).DataType, 'Bus:', '')) ''''];
                return;
            else
                [subBusDim, errMsg] = checkSubBusDims(subBusObj, dataAccessor);
                if prod(subBusDim) > 1
                    return;
                end
            end
        end
    end
end
