function [flags, A, B] = setfunCheckArgs(setfun, A, B, varargin)
%SETFUNCHECKARGS Check validity of function call and extract valid flags
%   This function throws errors if call is invalid.
%   First input argument is a function handle to the setfunction of
%   interest.
%   The other input arguments are copied from the setfunction call.

%   Copyright 2023 The MathWorks, Inc.

distributedutil.CodistParser.verifyNonCodistributedInputs(varargin);


argList = distributedutil.CodistParser.gatherElements(varargin);
funName = upper(func2str(setfun));

% We don't support tables, timetables, categoricals, datetime and duration  
% yet, so immediately error for these
if istabular(A) || iscategorical(A) || isdatetime(A) || isduration(A)
    error(message('parallel:array:UnsupportedFunction', funName, underlyingType(A)));
end
if istabular(B) || iscategorical(B) || isdatetime(B) || isduration(B)
    error(message('parallel:array:UnsupportedFunction', funName, underlyingType(B)));
end

% Combination of char/string and cellstr is not supported.
if (iscellstr(A) && (ischar(B) || isstring(B))) || ((ischar(A) || isstring(A)) && iscellstr(B))
    error(message("parallel:distributed:SetFcnUnsupportedCharCellStr", funName));
end

% Use the local function to check syntax and throw appropriate errors
distributedutil.validateSyntax(setfun, [{A}, {B}, argList]);

flags = {};
funName = upper(func2str(setfun));
if ~isempty(argList)
    if any(cellfun(@(x) matlab.internal.math.partialMatch(x, "legacy"), argList))
        error(message('parallel:distributed:SetFunctionLegacyFlagNotSupported'))
    end
    if any(cellfun(@(x) matlab.internal.math.partialMatch(x, "rows"), argList))
        flags = {'rows'};
        if (size(A, 2) ~= size(B, 2))
            eMessage = sprintf("MATLAB:%s:AandBColnumAgree", funName);
            error(message(eMessage))
        end
    end
    if any(cellfun(@(x) matlab.internal.math.partialMatch(x, "stable"), argList))
        flags = [flags {'stable'}];
    end
end

end
