function out = getInfo(h,itemOrder)

%   Copyright 2014-2020 The MathWorks, Inc.

buffer = '';
if nargin<2
    itemOrder = '';
else
    itemOrder = [ ' #', num2str( itemOrder ) ];
end
comment = h.BuilderApplication.getDirective( 'Comment' );
hP = coder.make.internal.Printer( comment );
% --------------------------------------
% Start writing
% --------------------------------------
% Heading
hP.printBorder();
hP.printComment( message( 'coder_compile:toolchain:Disp_ToolchainName', itemOrder, h.Name ) )
hP.printComment( message( 'coder_compile:toolchain:Disp_SupportedVersion', h.SupportedVersion ) )
hP.printComment( message( 'coder_compile:toolchain:Disp_FormatVersion', h.FormatVersion ) )
hP.printComment( message( 'coder_compile:toolchain:Disp_Revision', h.Revision ) )
hP.printBorder();
% General
printGeneralToolchainInfo();
% Include files
printIncludeFiles();
% Macros
printMacros();
buffer = hP.Buffer;
% Build tools
printBuildTools( h.BuildTools )
printBuildTools( h.PrebuildTools )
printBuildTools( h.PostbuildTools )
printBuildTools( h.BuilderApplication )
% Build config settings
printBuildConfigs();
out = buffer;
% --------------------------------------
% Helpers
% --------------------------------------
    function printGeneralToolchainInfo
        % ------------------
        % Attributes
        % ------------------
        hP.printBlankLine();
        hP.printComment( message( 'coder_compile:toolchain:Disp_Platform', h.Platform ) )
        hP.printComment( message( 'coder_compile:toolchain:Disp_SupportedLanguages', coder.make.internal.cell2str( h.SupportedLanguages, ',' ) ) )
        % ------------------
        % Setup/Cleanup
        % ------------------
        hP.printSectionTitle( message( 'coder_compile:toolchain:Disp_SetupCleanup' ) )
        printSetupCommands( 'MATLAB Setup', h.MATLABSetup );
        printSetupCommands( 'MATLAB Cleanup', h.MATLABCleanup );
        printSetupCommands( 'Shell Setup', h.ShellSetup );
        printSetupCommands( 'Shell Cleanup', h.ShellCleanup );
        % ------------------
        % Attributes
        % ------------------
        printAttributes();
        hP.printBlankLine();
    end
% ------------------
% Setup/Cleanup
% ------------------
    function printSetupCommands(desc,args)
        if isempty( args )
            msg = message( 'coder_compile:toolchain:Disp_None' );
            hP.println( [ desc, ': ', msg.getString() ] );
        else
            hP.println( [ desc, ': ' ] );
            for j = 1:numel( args )
                hP.println( '\t%s', strrep( args{ j }, sprintf( '\n' ), sprintf( '\n\t' ) ) );
            end
        end
    end
% ------------------
% Attributes
% ------------------
    function printAttributes
        sectionTitle = message( 'coder_compile:toolchain:Disp_Attributes' );
        attributes = h.Attributes.keys();
        numAttributes = numel( attributes );
        if numAttributes==0
            hP.printSectionTitle( sectionTitle );
            hP.println( message( 'coder_compile:toolchain:Disp_None' ) )
            return
        end
        % Uncomment if we want to hide certain internal attributes:
        % internalAttributesOnly = {'RequiresCommandFile', 'RequiresBatchFile'};
        % [~, idx] = ismember(internalAttributesOnly, attributes);
        % idx(idx==0) = []; % remove zero indexes
        % attributes(idx) = []; % remove internal-only attributes
        % numAttributes = numel(attributes);
        % if numAttributes==0
        %     hP.printSectionTitle(sectionTitle);
        %     hP.println(message('coder_compile:toolchain:Disp_None'))
        %     return
        % end
        valuestr = cell( 1, numAttributes );
        for i = 1:numAttributes
            attrib = attributes{ i };
            value = h.getAttribute( attrib );
            datatype = class( value );
            if isnumeric( value )
                datatype = 'numeric';
            elseif iscellstr( value )
                datatype = 'cellstr';
            end
            switch datatype
                case 'logical'
                    if value
                        valuestr{ i } = 'true';
                    else
                        valuestr{ i } = 'false';
                    end
                case 'numeric'
                    valuestr{ i } = num2str( value );
                case 'char'
                    valuestr{ i } = value;
                case 'cellstr'
                    valuestr{ i } = coder.make.internal.cell2str( value, ',' );
                otherwise
                    valuestr{ i } = [ '<', datatype, '>' ];
            end
        end
        hP.printAlignedMacrosAndValues( attributes, valuestr, sectionTitle );
    end
    function printIncludeFiles
        if ~isempty( h.InlinedCommands )
            hP.printSectionTitle( message( 'coder_compile:toolchain:Disp_InlinedCommands' ) )
            for i = 1:numel( h.InlinedCommands )
                hP.println( h.InlinedCommands{ i } );
            end
        end
    end
    function printBuildTools(tools)
        if isa( tools, 'coder.make.util.List' )
            iter = coder.make.util.ListIterator( tools );
            iter.pointToStart();
            while ~iter.endOf()
                tool = iter.next();
                if ~h.SupportsBuildingMEXFuncs && strcmp( tool.Name, 'MEX Tool' )
                    % Do not print
                    continue
                end
                buffer = [ buffer, tool.info() ];  %#ok<AGROW>
            end
        else
            buffer = [ buffer, tools.info() ];
        end
    end
    function printBuildConfigs
        cfgs = h.BuildConfigurations.values;
        for i = numel( cfgs ):-1:1
            buffer = [ buffer, cfgs{ i }.info() ];  %#ok<AGROW>
        end
    end
    function printMacros
        tokens = h.Macros.keys();
        tokenValues = h.Macros.values();
        numMacros = h.Macros.length();
        if numMacros==0
            return
        end
        % Print empty macros
        uninitTokens = h.getUninitializedMacros();
        numUninitMacros = numel( uninitTokens );
        if numUninitMacros>0
            hP.printSectionTitle( message( 'coder_compile:toolchain:Disp_MacrosDefinedElsewhere' ) )
        end
        for idx = 1:numUninitMacros
            hP.printComment( uninitTokens{ idx } )
        end
        % Print non-empty macros
        hP.printAlignedMacrosAndValues( tokens, tokenValues, 'MACROS' )
        hP.printBlankLine();
        return
        %     first = true;
        %     [~, idx] = max(cellfun(@numel, tokens));
        %     longest = numel(tokens{idx}); % used for inserting spaces for visual effects
        %     for idx=1:numMacros
        %         if ~isempty(tokenValues{idx}) || ischar(tokenValues{idx})
        %             if first
        %                 hP.printSectionTitle('MACROS');
        %                 first = false;
        %             end
        %             spaces = repmat(' ', 1, longest - numel(tokens{idx}));
        %             if ischar(tokenValues{idx})
        %                 hP.println(['%s' spaces ' = %s'], tokens{idx}, tokenValues{idx})
        %             else
        %                 values = tokenValues{idx};
        %                 values(cellfun('isempty', values)) = []; % remove empty cell elements
        %                 numValues = numel(values);
        %                 if numValues==1
        %                     hP.println(['%s' spaces ' = %s'], tokens{idx}, values{1})
        %                 else % >1
        %                     hP.printMultiLine(tokens{idx}, values, spaces)
        %                 end
        %             end
        %         end
        %     end
    end
end
