function dist = checkArgsForFastEuc(dist,isSparse,cacheSize,mx,dataClass)
%CHECKARGSFORFASTEUC Return the correct distance metric after checking
%arguments for fast Euclidean distance.
%   DIST = checkArgsForFastEuc(DIST,ISSPARSE,CACHESIZE,MX,DATACLASS)
%   returns distance metric after checking arguments. If cachesize is not
%   enough or input data is sparse, regular Euclidean distance should be
%   used instead.
%   On input, DIST is a string defining input distance metric, ISSPARSE is
%   a logical value indicating whether input data is sparse, CACHESIZE is
%   a numeric value specifying the size of cache in megabytes (MB) or a 
%   string of value "maximal", MX is the number of samples in the input 
%   data set (numeric), and DATACLASS is the class of input data (string).

%   Copyright 2022 The MathWorks, Inc.

if nargin > 2
    checkCacheSize = true;
else
    checkCacheSize = false;
end

% If Fast Euclidean distance could not be used, find its corresponding 
% regular Euclidean distance
switch dist
    case 'fse'
        newdist = 'seu';
    case 'fastseuclidean'
        newdist = 'seuclidean';
    case 'fqe'
        newdist = 'sqe';
    case 'fastsquaredeuclidean'
        newdist = 'squaredeuclidean';
    case 'feu'
        newdist = 'euc';
    case 'fasteuclidean'
        newdist = 'euclidean';
end

%% Fast Euclidean distance does not support sparse data
if isSparse
    switch dist
        case {'feu' 'fasteuclidean'}
            warning(message('stats:pdist:ReplaceFastEucWithRegularEuc','fasteuclidean','euclidean'));
        case {'fse' 'fastseuclidean'}
            warning(message('stats:pdist:ReplaceFastEucWithRegularEuc','fastseuclidean','seuclidean'));
        case {'fqe' 'fastsquaredeuclidean'}
            warning(message('stats:pdist:ReplaceFastEucWithRegularEuc','fastsquaredeuclidean','squaredeuclidean'));
    end
    dist = newdist;
    return;
end

%% Check cachesize
if ~checkCacheSize
    return;
end

if (statslib.internal.isString(cacheSize))
    cacheSize = convertStringsToChars(cacheSize);
end

if (~statslib.internal.isString(cacheSize) || ~strncmpi(cacheSize,'maximal',length(cacheSize))) ...
        && ( ~isscalar(cacheSize) || ~isfloat(cacheSize) ...
        || cacheSize<=0  || isnan(cacheSize) || ~isreal(cacheSize) )
    error(message('stats:lasso:BadCacheSize'));
end

bytePerElem = bytePerElement(dataClass);

% If numeric, check if it can hold at least M-by-1 vector
if isnumeric(cacheSize)
    if mx*bytePerElem > cacheSize*1e6
        warning(message('stats:pdist2:CacheIsNotEnough'));
        dist = newdist;
    end
end

end

function bytePerElem = bytePerElement(outClass)
if strcmpi(outClass, 'double')
    bytePerElem = 8;
else
    bytePerElem = 4;
end
end