function updated = rpp_update_doc(varargin)
% RPP_UPDATE_DOC Update built-in S-functions documentation.
%    The documentation is updated based on the YAML comment in .c files.
%    The number of updated blocks is returned.
if nargin > 0,
    op = varargin{1};
else
    op = 'update';
end
open('rpp_lib');
set_param('rpp_lib', 'Lock', 'off');
blocks = find_system('rpp_lib', 'Type', 'block');
updated = 0;
for i=1:length(blocks),
    block = blocks{i};
    params = get_param(block, 'ObjectParameters');
    fields = fieldnames(params);

    disp(['Processing ' blocks{i}]);

    updated = updated + process_param(op, block, 'MaskHelp', '--html');
    updated = updated + process_param(op, block, 'MaskPromptString', '--maskpromptstring');
    updated = updated + process_param(op, block, 'MaskType', '--masktype');
    %updated = updated + process_param(op, block, 'MaskDescription', '--maskdesc');
end
set_param('rpp_lib', 'Lock', 'on');

function output = run_doc_parse(fn, opts)
    % We have to unset Matlab's library path in order to run pandoc - it
    % needs newer libc than the one shipped with Matlab
    [rc, output] = system(['unset LD_LIBRARY_PATH; scripts/doc_parse.py ' opts ' ' fn '.c']);
    if rc ~= 0,
        disp(output)
        throw(MException('rpp:pandoc_failure', ['Failed to extract doc from ' fn '.c']))
    end

function print_diff(fn, param, old, new)
    fnold = [fn '.' param '.old'];
    f = fopen(fnold, 'w');
    fprintf(f, '%s', old);
    fclose(f);

    fnnew = [fn '.' param '.new'];
    f = fopen(fnnew, 'w');
    fprintf(f, '%s', new);
    fclose(f);

    [rc, diff] = system(['diff -u ' fnold ' ' fnnew]);
    disp(diff);
    delete(fnold);
    delete(fnnew);

function updated = process_param(op, block, param, opts)
    fn = get_param(block, 'FunctionName');
    new_content = run_doc_parse(fn, opts);
    old_content = get_param(block, param);

    if strcmp(param, 'MaskType') || ...
       strcmp(param, 'MaskPromptString'),
        new_content = deblank(new_content);
    end

    if ~strcmp(old_content, new_content),
        if strcmp(op, 'diff'),
            disp([block ': ' param ' not up-to-date'])
            print_diff(fn, param, old_content, new_content)
        else
            set_param(block, param, new_content)
        end
        updated = 1;
    else
        updated = 0;
    end
