% ISessionNotifier Interface to parallel.Pool notifications
%    During creation of a parallel pool, we need to issue
%    notifications before the pool is available.

% Copyright 2020-2021 The MathWorks, Inc.
classdef ISessionNotifier < handle

    methods (Abstract)
        sessionInfo = buildSessionInfo(obj);
        sessionInfo = notifyAboutToStart(obj, sessionInfo, clusterType, clusterName)
        sessionInfo = notifyStarting(obj, sessionInfo, varargin)
        notifyAbortByUser(obj, sessionInfo)
        notifyFailedToStart(obj, sessionInfo, errOrMessage)
    end
    methods (Static)
        function obj = getInstance()
            persistent INSTANCE
            if isempty(INSTANCE)
                % Get new notifier of correct type for version switch
                INSTANCE = iCreateNotifier();
            else
                % Verify existing notifier is of correct type for current
                % value of version switch
                if ~iValidateNotifier(INSTANCE)
                    INSTANCE = iCreateNotifier();
                end
            end
            obj = INSTANCE;
        end
        function info = buildAboutToStartInfo(clusterType, config)
        % Build a SessionInfo using the current notifier when about to start.
            notifier = parallel.internal.pool.ISessionNotifier.getInstance();
            info = notifier.buildSessionInfo();
            info = notifier.notifyAboutToStart(info, clusterType, config);
        end
    end
end

function notifier = iCreateNotifier()
import parallel.internal.apishared.ExperimentalVersions

% PCT_Java_Transition_TODO g2364333 - Remove
% ExperimentalVersion switching code and java paths
if strcmp(ExperimentalVersions.get().PLRVersion, ExperimentalVersions.Spf)
    notifier = parallel.internal.pool.CppBackedSessionNotifier();
else
    if ~usejava('jvm')
        error(message('parallel:internal:cluster:JVMNotPresentForPool'));
    end
    notifier = parallel.internal.pool.JavaBackedSessionNotifier();
end
end

function valid = iValidateNotifier(notifier)
import parallel.internal.apishared.ExperimentalVersions

% PCT_Java_Transition_TODO g2364333 - Remove
% ExperimentalVersion switching code and java paths
if strcmp(ExperimentalVersions.get().PLRVersion, ExperimentalVersions.Spf)
    valid = isa(notifier, 'parallel.internal.pool.CppBackedSessionNotifier');
else
    valid = isa(notifier, 'parallel.internal.pool.JavaBackedSessionNotifier');
end
end
