function removeLinkables(this, namesToRemove, groupsToRemove, groupsToKeep)
%removeLinkables removes specified linkable objects from buildInfo

% Copyright 2021 The MathWorks, Inc.

arguments
    this
    namesToRemove string = []
    groupsToRemove string = []
    groupsToKeep string = []
end

if isempty(this.LinkablesDirect)
    return
end

% Remove all linkables that match criteria
i_removeLinkables(this, namesToRemove, groupsToRemove, groupsToKeep);


% Cache must be refreshed after removal is complete
this.LinkablesDirectChecksum = [];



% Remove linkables matching criteria for removal
function i_removeLinkables(linkable, namesToRemove, groupsToRemove, groupsToKeep)

% Remove direct linkables (that match criteria for removal)
i_removeLinkablesDirect(linkable, namesToRemove, groupsToRemove, groupsToKeep);

% Traverse the remaining linkables at this level
linkablesDirectRemaining = linkable.LinkablesDirect;
for i=1:length(linkablesDirectRemaining)
    % Load any direct children
    linkable = linkablesDirectRemaining(i);
    loadLinkObjBuildInfo(linkable);
    
    % Traverse the buildInfo hierarchy
    if ~isempty(linkable.BuildInfoHandle)
        i_removeLinkables(linkable.BuildInfoHandle, namesToRemove, groupsToRemove, groupsToKeep)
    end
end



function i_removeLinkablesDirect(buildInfo, namesToRemove, groupsToRemove, groupsToKeep)


namesToRemove = convertStringsToChars(namesToRemove);
groupsToRemove = convertStringsToChars(groupsToRemove);
groupsToKeep = convertStringsToChars(groupsToKeep);

if isempty(namesToRemove) && isempty(groupsToRemove)
    removeIdx = true(size(buildInfo.LinkablesDirect));
else
    removeIdx = false(size(buildInfo.LinkablesDirect));
end

if ~isempty(namesToRemove)
    [~, idx] = intersect({buildInfo.LinkablesDirect.Name}, namesToRemove, 'stable');
    removeIdx(idx) = true;
end

if ~isempty(groupsToRemove)
    [~, idx] = intersect({buildInfo.LinkablesDirect.Group}, groupsToRemove, 'stable');
    removeIdx(idx) = true;
end

if ~isempty(groupsToKeep)
    [~, idx] = intersect({buildInfo.LinkablesDirect.Group}, groupsToKeep, 'stable');
    removeIdx(idx) = false;
end
    
if any(removeIdx)
    % remove the designated linkable objects from the buildInfo
    buildInfo.LinkablesDirect(removeIdx) = [];
end
