function defaultUsername = pGetDefaultUsername()
; %#ok Undocumented
% Get the username of the user who started MATLAB.

% Copyright 2009-2023 The MathWorks, Inc.

persistent username
if isempty(username)
    username = iGetUsername();
end
defaultUsername = username;

end

function username = iGetUsername()

if system_dependent('isdmlworker')
    username = iGetUsernameOnWorker();
elseif iRunningLocalClient() || ~parallel.internal.mwa.isLoggedIn()
    % When MATLAB is running locally (e.g. MATLAB Desktop) or we are in an
    % environment in which the MathWorks Account is not logged in (e.g.
    % deployed web apps, see g2631047), we should use the system user the
    % process is owned by.
    username = iGetSystemUsername();
else
    % Otherwise, we are in an environment in which we should be able to get
    % a logged-in user (e.g. MATLAB Online (Server)) and we should use that
    % logged in user as the default user.
    username = iGetMWAUsername();
end

% username must never be empty as this causes an error on the worker when
% setting the licensed user. See g2412466. Populate with something and let
% this propagate to any potential licensing issue later.
if isempty(username)
    username = 'unknown';
    dctSchedulerMessage(1, 'Unable to deduce default user name');
    warning(message('parallel:cluster:FailedToResolveUsername'));
end

end

function username = iGetUsernameOnWorker()
% dmlworkers should use the PARALLEL_SERVER_USERNAME variable if set
username = getenv('PARALLEL_SERVER_USERNAME');
if isempty(username)
    % Otherwise fall back on the same methods we use for local clients
    username = iGetSystemUsername();
end
end

function tf = iRunningLocalClient()
import matlab.internal.capability.Capability
tf = Capability.isSupported(Capability.LocalClient);
end

function username = iGetSystemUsername()
% Try the process owner
username = parallel.internal.getProcessUserName();
if isempty(username)
    % Otherwise fall back on the OS-dependent environment variable
    % indicating the system user
    if ispc
        username = getenv('USERNAME');
    else
        username = getenv('USER');
    end
end
end

function username = iGetMWAUsername()
user = parallel.internal.mwa.ensureLoggedIn();
username = user.getUsername();
end
