function dependencies = calculateDependencies( fileList )
% calculateDependencies - A PCT wrapper around matlab.depfun.internal.requirements

% Copyright 2012-2020 The MathWorks, Inc.

if isdeployed
    dependencies = iDeployedRequirements( fileList );
else
    dependencies = matlab.depfun.internal.requirements( fileList, 'PCTWorker' );
end
end

function dependencies = iDeployedRequirements( fileList )
    % Strip the ctfroot from all files in the list before searching the manifest
    ctfRootString = [ctfroot() filesep()];
    fileList = cellfun( @(file) iRemoveStartString( file, ctfRootString ), fileList, 'UniformOutput', false );
    
    % There may be more than one UserManifest file, so search for all of them.
    manifestPattern = fullfile( ctfroot, '.META', '*_UserManifest.mat' );
    manifestFiles = dir( manifestPattern );
    dctSchedulerMessage( 6, 'Manifest files:\n%s\n', sprintf( '%s\n', manifestFiles.name ) );

    dependencies = cell( 1, numel( manifestFiles ) );
    for ii = 1:numel( manifestFiles )
        try
            manifestName = manifestFiles(ii).name;

            % Extract the prefix, and use it to construct the variable name.
            pattern = '[a-zA-Z]\w*(?=_UserManifest.mat)';
            varPrefix = regexp( manifestName, pattern, 'match', 'once' );

            manifestVariable = [varPrefix, '_manifest'];

            % Load only the relevant manifest variable from the manifest .mat file.
            mStruct = load( fullfile( ctfroot, '.META', manifestName ) );
            manifest = mStruct.(manifestVariable);

            % Calculate the requirements from the manifest.
            currentDependencies = manifest.requirements( fileList );
            if ~isempty( currentDependencies )
                dctSchedulerMessage( 4, 'Found dependencies from manifest for %s:\n%s', ...
                    manifestName, sprintf( '%s\n', currentDependencies{:} ) );
            end
            dependencies{ii} = currentDependencies;
        catch E
            % If getting dependencies from one of the manifests fails,
            % log the error and continue.
            dctSchedulerMessage( 1, 'Error finding dependencies from manifest', ...
                E );
        end
    end

    % We have a cell array of cell arrays of strings. Make this a flat cell array
    % of strings.
    dependencies = [dependencies{:}];
    if ~isempty( dependencies )
        % Construct a structure that looks like the result of
        % matlab.depfun.internal.requirements and only take the unique dependencies.
        dependencies = cellfun( @(x) struct( 'path', x ), unique( dependencies ) );
    end
end

function str = iRemoveStartString(str, startString)
if startsWith(str, startString)
    str = extractAfter(str, startString);
end
end
