function obj = permute(obj, perm)
%PERMUTE Permute array dimensions.
%   B = PERMUTE(A, ORDER)
%   
%   If A has dimension labels, the permutation must be only
%   among dimensions that have the same label.
%
%   Permutations are done implicitly, and only directly computed
%   if necessary for other operations.
%
%   See also PERMUTE, DLARRAY.

%   Copyright 2019-2022 The MathWorks, Inc.

if isa(perm, 'dlarray')
    perm = gather(extractdata(perm));
    
    % Dispatch to suitable function in case obj is not a dlarray.
    obj = permute(obj, perm);
    return;
end

% Use error checking inside permute for now:
permute(1, perm);

if length(perm) < ndims(obj)
    error(message('MATLAB:permute:tooFewIndices'));
else
    % Insert trailing 'U' dimensions for permute to work on.  They will be
    % dropped later if they are still trailing after permutation.
    obj = addTrailingODims(obj, length(perm));
end

origDims = dims(obj);

% Adjust ViewToDataMap
objperm = obj.ViewToDataMap;
if isempty(objperm)
    objperm = cast(perm, 'like', []);
    objperm = reshape(objperm, 1, []);
else
    [perm, objperm] = matchPermLengths(perm, objperm);
    
    objperm = objperm(perm);
end

if isequal(objperm, 1:numel(objperm))
    obj.ViewToDataMap = 1:0;
else
    obj.ViewToDataMap = objperm;
end

if ~isequal(dims(obj), origDims)
    error(message('deep:permute:ChangeDims'));
end

obj = dropTrailingODims(obj);

end


function [permx, permy] = matchPermLengths(permx, permy)
% If permx and permy have different lengths, extend the shorter one.
lx = length(permx);
ly = length(permy);
if lx > ly
    permy(ly+1:lx) = ly+1:lx;
elseif lx < ly
    permx(lx+1:ly) = lx+1:ly;
end
end
