function oldpath = rmpath(varargin)
%RMPATH Remove folder from search path.
%   RMPATH FOLDERNAME removes the specified folder from the current
%   matlab path.  Surround the FOLDERNAME in quotes if the name contains a
%   space.  If FOLDERNAME is a set of multiple folders separated by path
%   separators, then each of the specified folders will be removed.
%
%   RMPATH FOLDER1 FOLDER2 FOLDER3 removes all the specified folders from
%   the path.
%
%   Use the functional form of RMPATH, such as
%   RMPATH('folder1','folder2',...), when the folder specification is stored
%   in a variable or string.
%
%   P = RMPATH(...) returns the path prior to removing the specified paths.
%
%   Examples
%       rmpath c:\matlab\work
%       rmpath /home/user/matlab
%       rmpath /home/user/matlab:/home/user/matlab/test:
%       rmpath /home/user/matlab /home/user/matlab/test
%
%   See also ADDPATH, PATHTOOL, PATH, SAVEPATH, USERPATH, GENPATH, REHASH.

%   Copyright 1984-2023 The MathWorks, Inc.

    if nargin > 0
        [varargin{:}] = convertStringsToChars(varargin{:});
    end

    narginchk(1, Inf);

    if nargout>0
        oldpath = path;
    end

    ps = pathsep;

    % Make cell array of MATLABPATH directories
    cmdirs = regexp([matlabpath ps],['.[^' ps ']*' ps],'match')';

    % Check for and resolve any package specifiers in input
    resolveddirs = resolveAnyPackages('path',varargin{:});

    if isempty(resolveddirs)
        return
    end

    % Check, trim, and concatenate the input strings
    dirs = catdirs(mfilename, resolveddirs{:});

    % Convert to clean cells
    cdirs = parsedirs(dirs);

    % Absolutize input strings
    for i=1:length(cdirs)
        try
            cdirs{i} = [builtin('_canonicalizepath', cdirs{i}(1:end-1)) pathsep];
        catch
            % Could not absolutize a path and let later code issue a warning
        end
    end

    % Loop through directories to find out where to remove them
    if ~((matlab.internal.feature('packages') ~= int32(0)) && ~isempty(getenv("PACKAGE_SPIN")))
        doRemoveFromPath(cdirs, cmdirs);
    else
        % This is non-shipping code branch
        for n=1:length(cdirs)
            aFolder = strrep(cdirs{n}, pathsep, '');
            if doesPackageJsonFileExist(aFolder)
                [isRegistered, isOnPath] = isRegisteredAndIsOnPath(aFolder);
                if isRegistered && isOnPath
                    % package located at aFolder is registered and on the path
                    % Note:
                    %  Intentionally removing folder from the path instead of UNREGISTER
                    matlab.internal.package.removeFromTheSearchPathOrder(aFolder);
                elseif isRegistered && ~isOnPath
                    % no op (no need to rmpath) as
                    % aFolder is detected as registered package but OnThePath=false:
                elseif ~isRegistered
                    % aFolder is a normal folder
                    doRemoveFromPath(cdirs, cmdirs);
                end
            else
                % aFolder is a normal folder
                doRemoveFromPath(cdirs, cmdirs);
            end
        end
    end
end


function doRemoveFromPath(cdirs, cmdirs)
% Only do case sensitive search on UNIX
    if ispc
        cdirsCased = lower(cdirs);
        cmdirsCased = lower(cmdirs);
    else
        cdirsCased = cdirs;
        cmdirsCased = cmdirs;
    end

    % Loop through directories to find out where to remove them
    pmatch = false(size(cmdirs));
    for n=1:length(cdirsCased)
        pTemp = strcmp(cdirsCased{n},cmdirsCased);
        if ~any(pTemp)
            warning(message('MATLAB:rmpath:DirNotFound', cdirs{ n }( 1:end - 1 )));
        end
        pmatch = pmatch | pTemp;
    end

    % Remove the directories from the MATLABPATH string, and update the path
    if any(pmatch)
        cmdirs(pmatch) = [];
        matlabpath([cmdirs{:}])
    end
end

function tf = doesPackageJsonFileExist(aFolder)
    tf = exist(fullfile(aFolder, 'resources'), 'dir') && ...
         exist(fullfile(aFolder, 'resources', "mpackage.json"), 'file');
end

function [isRegistered, isOnPath] = isRegisteredAndIsOnPath(loc)
    installedPackages = matlab.mpm.internal.list();
    tmp = arrayfun(@(x)checkInstall(x, loc), installedPackages);
    if any(tmp)
        isRegistered = true;
        isOnPath = installedPackages(tmp).OnThePath;
    else
        isRegistered = false;
        isOnPath = false;
    end

    function y = checkInstall(p, loc)
        t = matlab.mpm.internal.info(p.Package);
        try
            y = isequal(builtin('_canonicalizepath', t.InstallationLocation), ...
                        builtin('_canonicalizepath', loc));
        catch
            y = false;
        end
    end
end
