classdef (Sealed) BuildInfoHelpers
% Helper class containing functions to manipulate build info for PIL
% workflows.

%   Copyright 2020 The MathWorks, Inc.

    methods (Static)
        function updateBuildInfoToSkipLinkLibsAndOptions(buildInfo)

            % For a SIL+PWS simulation, drop any
            % compiler/linker/archiver/defines options that are in the SkipForSil
            % group. Also, we must drop custom target compiler optimization
            % options (these can be specified by the model parameter
            % RTWCustomCompilerOptimizations and end up in the
            % OPTIMIZATION_FLAGS group)
            groupsToSkip = {'SkipForSil','OPTIMIZATION_FLAGS'};
            for groupIdx = 1:length(groupsToSkip)
                skipGroup = groupsToSkip{groupIdx};

                % link flags
                linkFlags = buildInfo.Options.LinkFlags;
                if ~isempty(linkFlags)
                    linkFlagsGroups = get(linkFlags,'Group');
                    skipGroupIdx = strcmp(linkFlagsGroups, skipGroup);
                    buildInfo.Options.LinkFlags = linkFlags(~skipGroupIdx);
                end

                % compile flags
                compileFlags = buildInfo.Options.CompileFlags;
                if ~isempty(compileFlags)
                    compileFlagsGroups = get(compileFlags,'Group');
                    skipGroupIdx = strcmp(compileFlagsGroups, skipGroup);
                    buildInfo.Options.CompileFlags = compileFlags(~skipGroupIdx);
                end

                % archive flags
                archiveFlags = buildInfo.Options.ArchiveFlags;
                if ~isempty(archiveFlags)
                    archiveFlagsGroups = get(archiveFlags,'Group');
                    skipGroupIdx = strcmp(archiveFlagsGroups, skipGroup);
                    buildInfo.Options.ArchiveFlags = archiveFlags(~skipGroupIdx);
                end

                % Defines
                buildInfo.deleteDefines(buildInfo.getDefines(skipGroup));
            end

            % libs - also include the linksandtargets group as this is
            % the existing group label for libs like IQmath.lib
            excludeGroupIDsForSil = {'linksandtargets', 'SkipForSil'};
            buildInfo.removeLinkObjects('', excludeGroupIDsForSil);
        end

        function updateBuildInfoToSkipFiles(buildInfo, langExts)

            % Remove source files in "SkipForInTheLoop" group in buildInfo
            removeSourceFiles(buildInfo, [], 'SkipForInTheLoop')

            % Remove any execution profiling timer stub functions
            coder_profile_stubs = coder.profile.ExecTimeConfig.EmptyTimerSrcName;

            % SIL/PIL application does not need to link against these
            additionalSkipFileNames = {
                'ert_main.'                    % SIL / PIL has its own main
                'rt_main.'                     % g758634
                'rt_malloc_main.'
                'rt_cppclass_main.'         % g1146592
                [coder_profile_stubs '.']
                [buildInfo.ModelName '_sf.']   % ERT S-fcn
                [buildInfo.ModelName '_bio.']  % g598514
                [buildInfo.ModelName '_pt.']}; % g598514
            
            numNames = numel(additionalSkipFileNames);
            if ~iscell(langExts)
                exts = {langExts};
            else
                exts = langExts;
            end
            numLangExts = numel(exts);
            additionalFilesToSkip = cell(numLangExts * numNames, 1);
            
            for i = 1:numNames
                for j = 1:numLangExts
                    index = (i - 1) * numLangExts + j;
                    additionalFilesToSkip{index} = [additionalSkipFileNames{i}, exts{j}];
                end
            end

            % Remove source files from buildInfo
            removeSourceFiles(buildInfo, additionalFilesToSkip);
        end

        function updateBuildInfoToSkipFilesSilAndPWS(buildInfo, isIdeLink)

            % Remove source files in "SkipForSil" and "SkipForInTheLoop" groups
            removeSourceFiles(buildInfo, [], {'SkipForInTheLoop', 'SkipForSil'})            
            
            if isIdeLink                    
                % additionally skip these files for SIL - these are listed in the
                % target pref block for idelink models. It was not possible to add
                % these to the SkipForSil group as they already have a group.
                tgtInfo = getTgtPrefInfo(buildInfo.ModelName);
                removeSourceFiles(buildInfo, tgtInfo.chipInfo.src);

                % idelink adds the shared source files to buildInfo - see
                % method update in linkfoundation.pjtgenerator.Project. If
                % we don't filter them out, they will appear on the
                % MODEL_MODULES list in the makefile. However, this will
                % cause build failures since the makefiles manage building
                % the shared src themselves.
                if ispc
                    group = 'rtwshared.lib';
                else
                    group = 'rtwshared.a';
                end
                
                removeSourceFiles(buildInfo, [], group);
            end

            rtw.pil.BuildInfoHelpers.updateBuildInfoToSkipLinkLibsAndOptions(buildInfo);
        end
        
        function addTargetSendAndReceiveBufferSizeDefines(buildInfo, sendSize, receiveSize)
            buildInfo.addDefines(sprintf('RTIOSTREAM_RX_BUFFER_BYTE_SIZE=%s',...
                 int2str(receiveSize)), 'OPTS');
            buildInfo.addDefines(sprintf('RTIOSTREAM_TX_BUFFER_BYTE_SIZE=%s',...
                 int2str(sendSize)), 'OPTS'); 
        end
    end

end
