function trueValues = validateTrueValues(X, trueValues, dataFormat)
% Verify the true values label and size match X data and return true values
% as dlarray.

%   Copyright 2019-2020 The MathWorks, Inc.

% Find how the arguments are formatted
firstArgumentIsLabeled = isempty(dataFormat);
secondArgumentIsLabeled = isa(trueValues, 'dlarray') && hasFormat(trueValues);

% Make sure dataFormat contains either the value of DataFormat or the
% labels of X
labelsX = dims(X);
if firstArgumentIsLabeled
    dataFormat = labelsX;
end

% Verify that there are enough labels for the true values
numLabels = numel(dataFormat);
if numLabels>1 && ndims(trueValues)>numLabels
    % The trueValues input has too many dimensions compared to X. Throw the
    % size mismatch error.
    error(message('deep:dlarray:LossSizeMismatch'))
end

if secondArgumentIsLabeled
    % Verify the ordered formats are identical
    if ~isequal(dims(trueValues), labelsX)
        error(message('deep:dlarray:LossDescriptorMismatch'));
    end
else
    % Create a dlarray with the data format of the input X 
    trueValues = dlarray(trueValues, dataFormat);
end

% Verify the sizes match after dlarray construction
if ~isequal(size(trueValues), size(X))
    if ~firstArgumentIsLabeled && secondArgumentIsLabeled
        % Throw a more general error message as size vectors are allowed to
        % be different for this case
        error(message('deep:dlarray:LossLabeledTargetMismatchSize'))
    else
        error(message('deep:dlarray:LossSizeMismatch'))
    end
end

% The dlarray methods should not accept logical input 
if islogical(trueValues)
    error(message('deep:dlarray:LogicalsNotSupported'));
end

end
