%PathInfo   Container for passing paths to workers for rmpath/addpath/cd/clear events.
%   PathInfo contains paths passed to rmpath/addpath/cd/clear events caught by
%   dctPathAndClearNotification when a pool is open.
%
%   See MATLABDrivePathMap, MATLABDriveUtils.

% Copyright 2016-2020 The MathWorks, Inc.

classdef ( Hidden, Sealed ) PathInfo
    properties ( SetAccess = immutable )
        %RawPaths   Paths associated with rmpath/addpath/cd/clear event.
        %  A cell array of chars representing the paths associated with an
        %  rmpath/addpath/cd/clear event.
        RawPaths
        %UNCPaths   UNC Paths associated with rmpath/addpath/cd/clear event.
        %  A cell array of chars representing the UNC paths associated with an
        %  rmpath/addpath/cd/clear event.
        UNCPaths
        %MATLABDrivePathMap  Translates RawPaths within the client's MATLAB Drive.
        %  A parallel.internal.apishared.MATLABDrivePathMap enabling
        %  translation of members of RawPaths that are within a client's MATLAB Drive
        %  folder into paths within a worker's MATLAB Drive folder.
        MATLABDrivePathMap
        %IsPathFrozen logical vector indicating whether each path should be frozen
        %  logical vector same size as RawPaths indicating whether each of those
        %  paths was added to the MATLAB path in 'frozen' mode.
        IsPathFrozen
        %IsPathBegin logical vector indicating whether each path is at the beginning or end
        %  Only used for addpath commands, otherwise empty.
        IsPathBegin
    end
    
    methods
        function obj = PathInfo( rawPaths, rawPathsForMap, isPathBegin )
            if nargin < 2
                rawPathsForMap = rawPaths;
            end
            
            if nargin < 3
                isPathBegin = [];
            end
            
            obj.RawPaths = rawPaths;
            obj.UNCPaths = cellfun( @dctReplaceDriveWithUNCPath, rawPaths, 'UniformOutput', false );
            obj.MATLABDrivePathMap = parallel.internal.apishared.MATLABDrivePathMap( rawPathsForMap );
            obj.IsPathFrozen = parallel.internal.general.isPathFrozen( rawPaths );
            obj.IsPathBegin = isPathBegin;
        end
        
        function debugString = getDebugString( obj )
            rawPathsDebugString = sprintf( 'PathInfo.RawPaths {%s}', strjoin( obj.RawPaths, ',' ) );
            pathMapDebugString = sprintf( 'PathInfo.%s', obj.MATLABDrivePathMap.getDebugString() );
            debugString = sprintf( '%s\n%s', rawPathsDebugString, pathMapDebugString );
        end
    end
    
    methods ( Static )
        function pathInfo = createAddPathInfo( rawPathsBegin, rawPathsEnd )
            rawPaths = [rawPathsBegin, rawPathsEnd];
            isPathBegin = [true(size(rawPathsBegin)), false(size(rawPathsEnd))];
            pathInfo = parallel.internal.apishared.PathInfo( rawPaths, rawPaths, isPathBegin );
        end
        
        function pathInfo = createRmPathInfo( rawPaths )
            pathInfo = parallel.internal.apishared.PathInfo( rawPaths );
        end
        
        function pathInfo = createCdPathInfo( rawPaths )
            pathInfo = parallel.internal.apishared.PathInfo( rawPaths );
        end
        
        function pathInfo = createClearPathInfo( rawArgs )
            % Only use last argument passed to clear event
            lastArg = rawArgs{ end };
            
            % Only apply MATLAB Drive translation for absolute paths for
            % clear events to avoid mistaking keywords like 'classes' or
            % 'functions' as relative paths
            if parallel.internal.apishared.FilenameUtils.isAbsolutePath( lastArg )
                absolutePaths = { lastArg };
            else
                absolutePaths = {};
            end
            
            pathInfo = parallel.internal.apishared.PathInfo( { lastArg }, absolutePaths, [] );
        end
        
        % PCT_Java_Transition_TODO (g2383489): Remove unused method after Java transition
        function byteData = getSerializedPathInfo( rawPaths, isPathBegin )
            %getSerializedPathInfo   Create a serialized PathInfo object
            %  Creates a serialized PathInfo object for use with
            %  cd/addpath/rmpath events.
            if nargin < 2
                isPathBegin = [];
            end
            
            pathInfo = parallel.internal.apishared.PathInfo( rawPaths, rawPaths, isPathBegin );
            % Note: we're assuming pathInfo will not exceed 2GB.
            byteData = distcompserialize( pathInfo );
        end
        
        % PCT_Java_Transition_TODO (g2383489): Remove unused method after Java transition
        function byteData = getSerializedClearPathInfo( rawArgs, ~ )
            %getSerializedClearPathInfo   Create a serialized PathInfo object
            %  Creates a serialized PathInfo object for use with clear events.
            pathInfo = parallel.internal.apishared.PathInfo.createClearPathInfo( rawArgs );
            
            % Note: we're assuming pathInfo will not exceed 2GB.
            byteData = distcompserialize( pathInfo );
        end
        
        % PCT_Java_Transition_TODO (g2383489): Remove unused method after Java transition
        function obj = getDeserializedPathInfo( byteData )
            %getSerializedClearPathInfo   Unpacks a serialized PathInfo object.
            obj = distcompdeserialize( byteData );
        end
    end
end
