function [Keys,Vals] = getKeyValuePair(h, varargin)
%GETMakeVars - returns strings formatted for use as makefile variables

% Copyright 2005-2019 The MathWorks, Inc.
    
%check the args to make sure they all conform to the expected format
args = locCheckArgs(varargin{:});

switch(args.type)
  case 'Tokens'
    Keys = get(h.Tokens,'Key');
    Vals = get(h.Tokens,'Val');
    Groups = get(h.Tokens,'Group');
  case 'BuildArgs'
    Keys = get(h.BuildArgs,'Key');
    Vals = get(h.BuildArgs,'Val');
    Groups = get(h.BuildArgs,'Group');    
  case 'MakeVars'
    Keys = get(h.MakeVars,'Key');
    Vals = get(h.MakeVars,'Val');
    Groups = get(h.MakeVars,'Group');    
end

% if there are no options, then return before filtering
if isempty(Keys)
    Keys = {};
    Vals = {};
    return;
end

if ~iscell(Keys)
    Keys = {Keys};
    Vals = {Vals};
end

% find the indices of the included groups (if specified
if ~isempty(args.incGroups)
    idx(1:length(Keys)) = false;
    % get the indices of the entries that match the include groups
    for i=1:length(args.incGroups)
        % get the indices of the entries that match the include groups
        if args.regexpSearch
            tmp = ~cellfun(@isempty,regexp(Groups,args.incGroups{i},'once'))';
        else
            tmp = strcmp(Groups,args.incGroups{i})';
        end
        
        % OR these indices with the current list
        idx = or(idx,tmp);
    end
else
    idx(1:length(Keys)) = true;
end

% find the indices of the excluded groups (if specified
if ~isempty(args.excGroups)
    % get the indices of the entries that match the exclude groups
    for i=1:length(args.excGroups)
        % get the indices that DON'T match the exclude groups
        if args.regexpSearch
            tmp = cellfun(@isempty,regexp(Groups,args.excGroups{i},'once'))';
        else
            tmp = ~strcmp(Groups,args.excGroups{i})';
        end
        
        % AND the non matching entries with the current list, thereby removing
        % the ones that do match.
        idx = and(idx,tmp);
    end
end


% if there are no files left, then return an empty cell array
if ~any(idx)
    Keys = {};
    Vals = {};
    return;
end

if ~isempty(Keys)
    Keys = Keys(idx);
end
if ~isempty(Vals)
    Vals = Vals(idx);
end

end

function args = locCheckArgs(varargin)


    persistent parserObj;

    if isempty(parserObj)
        
        kvLists = {'BuildArgs', 'Tokens', 'MakeVars'};
        % elements for the input parser are:
        %
        %  {{fieldname1, default, validator func}
        %   {fieldname2, default, validator func}
        %   {fieldname3, default, validator func}}
        
        pFields =...
            {{'type',         'BuildArgs',  @(x) any(strcmp(x, kvLists))}...
             {'regexpSearch', true, @islogical}...
             {'incGroups',    {}, @iscellstr}...
             {'excGroups',    {}, @iscellstr}...
            };
        
        [args, parserObj] = locParseInput(pFields,varargin{:});
    else
        args = locParseInput(parserObj,varargin{:});     
    end
end

function [args, parserObj] = locParseInput(pFields, varargin)

    parserObj = [];
    if isa(pFields,'inputParser')
        p = pFields;
    else
        p = inputParser;
        p.KeepUnmatched = true;
        p.StructExpand  = true;
        p.CaseSensitive = false; 

        for i=1:length(pFields)
            p.addParamValue(pFields{i}{1}, pFields{i}{2}, pFields{i}{3});
        end
        parserObj = p;
    end
    
    p.parse(varargin{:});
    args = p.Results;
    locErrorIfAdditionalArgs(p.Unmatched);
    
end

function locErrorIfAdditionalArgs(unmatched)

    f = fields(unmatched);
    if isempty(f)
        return;
    end
    badFields = sprintf('%s\n',f{:});
    
    DAStudio.error('RTW:buildInfo:UnknownArgs', 'getMakeVars', badFields);

end
