function [varargout] = timetable(varargin)
%TIMETABLE Build a distributed timetable from distributed arrays
%   DT = TIMETABLE(DROWTIMES,D1,D2,...) creates a distributed timetable DT from
%   distributed arrays D1, D2, ... using the distributed datetime or
%   duration vector DROWTIMES as the time vector. All arrays must be distributed
%   and have the same number of rows.
%   
%   DT = TIMETABLE(D1, D2, ..., 'RowTimes',DROWTIMES) creates a timetable
%   using the specified distributed datetime or duration vector, DROWTIMES, as 
%   the time vector. Other datetime or duration inputs become variables in DT.       
%   
%   DT = TIMETABLE(..., 'VariableNames', {'name1', ..., 'name_M'}) creates a
%   timetable containing variables that have the specified variable names.
%   The names must be valid MATLAB identifiers, and unique.
%   
%   DT = TIMETABLE(..., 'DimensionNames', {'dim1', 'dim2'}) creates a
%   timetable containing variables that have the specified dimension names.
%   The names must be valid MATLAB identifiers, and unique.
%   
%   Limitations:
%   1. The parameters 'SampleRate', 'TimeStep', and 'StartTime' are not supported.
%   2. The 'Events' property is not supported for distributed timetables.
%   
%   See also TIMETABLE, DISTRIBUTED.
%   


%   Copyright 2018-2023 The MathWorks, Inc.

% If NVP VariableNames is not specified, extract variable names from the
% input and add them as NVP to not lose that information inside the SPMD
% block.
numVars = matlab.bigdata.internal.util.countTableVarInputs(varargin);
inputs = varargin;

pnames   = {'VariableNames' 'RowTimes'  'SampleRate'  'SamplingRate'  'TimeStep'  'StartTime'  'DimensionNames'}; % SamplingRate is legacy
dflts    = {            []         []            []              []          []   seconds(0)                [] };
priority = [             0          0             1               0           0            1                 0 ]; % 'Sa' -> 'SampleRate', 'S' -> ambiguous
[varnames, ~, ~, ~, ~, ~, dimnames, supplied] ...
    = matlab.internal.datatypes.parseArgsTabularConstructors(pnames, dflts, priority, ...
                                                             "MATLAB:timetable:StringParamNameNotSupported", ...
                                                             varargin{numVars+1:end});
if supplied.SampleRate || supplied.SamplingRate || supplied.TimeStep || supplied.StartTime
    error(message("parallel:distributed:TimetableUnsupportedParam"));
end

if ~supplied.VariableNames
    % Get the workspace names of the input arguments from inputname if
    % variable names were not provided. Need these names before looking
    % through vars for the time vector.
    varnames = repmat({''}, 1, numVars);
    for i = 1:numVars
        varnames{i} = inputname(i);
    end
end

% Setup rowtimes
rowtimesName = getString(message("MATLAB:timetable:uistrings:DfltRowDimName"));
if ~supplied.RowTimes
    if supplied.VariableNames
        rowtimesName = inputname(1);
    else
        % First input will be used as rowtimes, so remove from var list
        rowtimesName = varnames{1};
        varnames(1) = [];
    end
    numVars = numVars - 1; %#ok<NASGU>
end

if supplied.DimensionNames
    % Overwrite rowtimesName.
    if ~matlab.internal.datatypes.isText(dimnames)
        error(message("MATLAB:table:InvalidDimNames"))
    elseif iscell(dimnames) && ~isempty(dimnames)
        rowtimesName = dimnames{1};
    elseif isstring(dimnames) && numel(dimnames)>1
        rowtimesName = dimnames(1);
    else % original dimnames was a string and not an array of string, or empty
        error(message("MATLAB:table:IncorrectNumberOfDimNames"))
    end
end

if ~supplied.VariableNames
    % Fill in default names for data args where inputname couldn't. Do
    % this after removing the time vector from the other vars, to get the
    % default names numbered correctly.
    empties = cellfun("isempty", varnames);
    if any(empties)
        varnames(empties) = matlab.internal.tabular.defaultVariableNames(find(empties));
    end
    % Make sure default names or names from inputname don't conflict
    varnames = matlab.lang.makeUniqueStrings(varnames, {}, namelengthmax);
    inputs = [inputs, {'VariableNames', varnames}];
end

varargout = cell(1, max(1, nargout));
[varargout{:}] = distributedutil.distributedSpmdWrapper(@timetable, inputs{:});

if ~isempty(rowtimesName)
    varargout{1} = distributedutil.distributedSpmdWrapper(@hSetTimeName, varargout{1}, rowtimesName);
end

end
