classdef (Hidden = true) OutOfProcessExecUtils < handle
% Utility class for C Caller out-of-process execution

% Copyright 2018 The MathWorks, Inc.

    methods (Static = true)
        function [exePID, exeOutputFile, exeErrorFile, serverPort] = launchProcess(command, argString)
            % Launch the process
            [exePID, exeOutputFile, exeErrorFile] = rtw.connectivity.Utils.launchProcess(command, argString);
            exePID = int2str(exePID);
            
            % Retrieve the server port information
            nRetry=50;
            while nRetry > 0
                % check for file existence before calling fileread
                outputFileExists = exist(exeOutputFile, 'file');
                if outputFileExists
                    % found output file
                    break;
                end
                % pause then try again
                pause(0.1);
                nRetry = nRetry - 1;
            end
            if ~outputFileExists
                rtw.connectivity.ProductInfo.error('target', 'MissingOutputFile', ...
                    exeOutputFile);
            end
            
            [portCell, outputFileContents] = rtw.connectivity.OutOfProcessExecUtils.readServerPortNumber(exeOutputFile);
            
            if isempty(portCell)
                rtw.connectivity.ProductInfo.error('target', 'UnknownServerPort', ...
                    outputFileContents, [command ' ' argString]);
            end
            serverPort = portCell{1};
        end

        function isOK = isDebuggingEnabledAndExeAlive(~, exePID)
            % The first input argument is modelHandle, which is reserved
            % for future use.
            narginchk(2, 2);
            
            isOK = 0;
            if slfeature('OutOfProcessExecution') > 0 && psUtils('isalive', exePID)
                isOK = 1;
            end
        end
    end
    
    methods (Static = true, Access = private)
        function [portCell, outputFileContents] = readServerPortNumber(outputFile)
            nRetry=150;
           
            while nRetry > 0
                outputFileContents = fileread(outputFile);
                portCell = regexp(outputFileContents, ...
                    'Server Port Number: (\d*)', 'tokens', 'once');
                if ~isempty(portCell)
                    % found server port number
                    break;
                end
                % Pause then try again
                pause(0.1);
                nRetry = nRetry - 1;
            end
        end
    end
end
