function discoverGenericClusters(folder)
%DISCOVERGENERICCLUSTERS - Run Generic cluster discovery and display
% available cluster profiles.

%   Copyright 2022-2023 The MathWorks, Inc.

arguments
    folder = pwd
end

msg = message("parallel:internal:cluster:DiscoveringClustersInFolder", folder);
fprintf("%s\n\n", msg.getString());

% Create discoverer
genericDiscoverer = parallel.internal.discover.FilesystemGeneric(folder);

% Listen for successful cluster discoveries
clusterFoundListener = event.listener(genericDiscoverer, "ClusterFound", @iPrintDiscoveredCluster);

% Listen for rejected clusters and other messages
logMessageListener = event.listener(genericDiscoverer, "LogMessage", @iPrintMessage);

% Do discovery
genericDiscoverer.discover(@false);
end

function iPrintMessage(~, evtData)
fprintf("%s\n\n", evtData.Message);
end

function iPrintDiscoveredCluster(~, evtData)
cluster = cell2struct(evtData.ClusterPropValues, evtData.ClusterPropNames, 2);
for name = ["JobStorageLocation", "AdditionalProperties"]
    if isfield(cluster, name) && iIsTextScalar(cluster.(name))
        try
            cluster.(name) = jsondecode(cluster.(name));
        catch
        end
    end
end

fprintf("Discovered '%s' cluster with the following properties:\n", evtData.Type);
iDisplayStruct(cluster, defaultInset);
fprintf("\n");
end

function tf = iIsTextScalar(val)
tf = isStringScalar(val) || (ischar(val) && isrow(val));
end

function iDisplayStruct(s, inset)
cellfun(@(name) iDisplay(name, s.(name), inset), fieldnames(s));
end

function iDisplay(name, value, inset)
fprintf("%s%s:", blanks(inset), name);
if isstruct(value)
    fprintf("\n");
    iDisplayStruct(value, inset + defaultInset);
else
    fprintf(" %s\n", strjoin(string(value)));
end
end

function inset = defaultInset()
inset = 4;
end
