function [hdrFilesOut, srcFilesOut, nonBuildFilesOut, linkFlagsOut, includePathsOut] = ...
  dspModifyBuildInfo(model, productStr, productPath, hdrFiles, srcFiles, nonBuildFiles, linkFlags, libNames, libPaths)
%DSPMODIFYBUILDINFO Add to the build information for the model according to the product

% Copyright 2007-2023 The MathWorks, Inc.

% The arguments to this file are as follows:
% 1) The model (or 'System_objects')
% 2) The productStr (i.e. dspblks, comm, vipblks)
% 3) The productPath to the files that are required. This might only be meaningful
%    in conjunction with the product specification.
% 4-6) A cell array of filenames.
% 7) A cell array of strings (link flags).

% Get product-specific paths
[srcPath, hdrPath, includePaths] = ...
    getProductSpecificPaths(productStr, productPath);

[linkFlags, sysLinkFlags] = separateLinkAndSysFlags(productStr, linkFlags);

% For nonBuildFiles without paths, attempt to supply them
nonBuildFiles = findNonBuildFiles(nonBuildFiles);

% Transform the inputs into cell arrays. This is necessary because this
% may be called from TLC, where it is not possible to create cell arrays.
hdrFiles      = createCell(hdrFiles);
srcFiles      = createCell(srcFiles);
nonBuildFiles = createCell(nonBuildFiles);
sysLinkFlags  = createCell(sysLinkFlags);
linkFlags     = createCell(linkFlags);
libNames      = createCell(libNames);
libPaths      = createCell(libPaths);

% The return values will be used to call into SysObjModifyBuildInfo
hdrFilesOut  = hdrFiles;
srcFilesOut  = srcFiles;
nonBuildFilesOut = nonBuildFiles;
linkFlagsOut = [sysLinkFlags, linkFlags];
includePathsOut = includePaths;

updateBuildInfo = false;
buildInfo = [];
if ~isempty(model) && ~strcmp(model, 'System_objects') 
    modelCodegenMgr = coder.internal.ModelCodegenMgr.getInstance(model);
    if ~isempty(modelCodegenMgr)
        updateBuildInfo = true;
        buildInfo = modelCodegenMgr.BuildInfo;
    end
end

if ~exist(srcPath, 'dir')
   updateBuildInfo = false;
end

if updateBuildInfo
    dspsharedModifyBuildInfo(buildInfo, hdrFiles, hdrPath, srcFiles, srcPath, includePaths, nonBuildFiles, sysLinkFlags, linkFlags, libNames, libPaths, model);
else
  if ~isempty(hdrPath)
      hdrFilesOut=cellfun(@(hdrFileOut)(fullfile(hdrPath, hdrFileOut)), hdrFilesOut, 'UniformOutput', false);
  end
  if ~isempty(srcPath)
      srcFilesOut=cellfun(@(srcFileOut)(fullfile(srcPath, srcFileOut)), srcFilesOut, 'UniformOutput', false);
  end
end
end
% =========================================================================

function [srcPath, hdrPath, includePaths] = ...
    getProductSpecificPaths(productStr, productPath)

switch productStr
  case {'dsp_ml_core','shared_dspblks'}
    srcPath = fullfile(matlabroot,'toolbox','shared','spc','src_ml','extern','src');
    hdrPath = fullfile(matlabroot,'toolbox','shared','spc','src_ml','extern','include');
    includePaths = {hdrPath};
    
  case {'shared_dspvision', 'shared_dspvision_mmio'}
    srcPath = fullfile(matlabroot, 'toolbox','shared','dsp','vision','matlab','include');
    hdrPath = srcPath;
    includePaths = {hdrPath};
    if (strcmp(productStr,'shared_dspvision_mmio'))
      % For multimedia/VideoDefs.hpp
      includePaths(end+1) = {fullfile(matlabroot,'extern','include','multimedia')};
    end
  
  case 'shared_multimedia'
    srcPath = fullfile(matlabroot,'extern','include','multimedia');
    hdrPath = srcPath;
    includePaths = {hdrPath};
    
  case 'dspblks'
    if strcmp(productPath, 'include')
      srcPath = fullfile(matlabroot, 'toolbox','dsp', 'dsp','include');
    else
      srcPath = fullfile(matlabroot,'toolbox','dsp','dsp','extern','src',productPath);
    end
    hdrPath = fullfile(matlabroot, 'toolbox','dsp','dsp','include');
    % For multimedia/VideoDefs.hpp
    includePaths = {fullfile(matlabroot,'extern','include','multimedia')};
    % for dsp_rt.h and (dsp_iso_math_rt.h that is included by dsp_rt.h)
    includePaths(end+1) = {fullfile(matlabroot, 'toolbox','shared','dsp','vision','matlab','include')};
    includePaths(end+1) = {fullfile(matlabroot, 'toolbox','dsp','halidesim','include')};
    includePaths(end+1) = {hdrPath};

  case 'audio'
    srcPath = fullfile(matlabroot, 'toolbox','dsp','dsp','include');
    hdrPath = fullfile(matlabroot, 'toolbox','dsp','dsp','include');
    includePaths = {hdrPath};
    
  case 'dspextern'
    srcPath = fullfile(matlabroot,'toolbox','dsp','dsp','extern','src',path);
    hdrPath = fullfile(matlabroot, 'toolbox','dsp','dsp','extern', 'src', 'export', 'include', 'src');
    includePaths = {hdrPath};
    
  case 'vipblks'
    if strcmp(productPath, 'include')
      srcPath = fullfile(matlabroot, 'toolbox','vision','include');
    else
      srcPath = fullfile(matlabroot,'toolbox','vision','visionrt',productPath);
    end
    hdrPath = fullfile(matlabroot, 'toolbox','vision','visionrt','export','include','visionrt');
    % for dsp_rt.h and (dsp_iso_math_rt.h that is included by dsp_rt.h)
    includePaths = {fullfile(matlabroot, 'toolbox','shared','dsp','vision','matlab','include')};
    % for other vision include files
    includePaths(end+1) = {fullfile(matlabroot, 'toolbox','vision','include')};
    includePaths(end+1) = {fullfile(matlabroot, 'toolbox','vision','visionrt','export','include')};
    includePaths(end+1) = {hdrPath};
    
  case 'visionio'
    if strcmp(productPath, 'include')
      srcPath = fullfile(matlabroot, 'toolbox','vision','include');
    else
      srcPath = fullfile(matlabroot,'toolbox','vision','visionrt',productPath);
    end
    hdrPath = fullfile(matlabroot, 'toolbox','vision','include');
    % for dsp_rt.h and (dsp_iso_math_rt.h that is included by dsp_rt.h)
    includePaths = {fullfile(matlabroot, 'toolbox','shared','dsp','vision','matlab','include')};
    includePaths(end+1) = {hdrPath};
       
  case 'imaqblks'
    srcPath = fullfile(matlabroot, 'toolbox', 'imaq', 'imaqblks', 'include');
    hdrPath = fullfile(matlabroot, 'toolbox', 'imaq', 'imaqblks', 'include');
    includePaths = {hdrPath};
    
  case 'vntblks'
    srcPath = fullfile(matlabroot, 'toolbox', 'vnt', 'vntblks', 'include');
    hdrPath = fullfile(matlabroot, 'toolbox', 'vnt', 'vntblks', 'include');
    includePaths = {hdrPath};
    
  case 'shared_can'
    srcPath = fullfile(matlabroot, 'toolbox', 'shared', 'can', 'src', 'scanutil');
    hdrPath = fullfile(matlabroot, 'toolbox', 'shared', 'can', 'src', 'scanutil');
    includePaths = {hdrPath};

  case 'shared_tammex'
    % The srcPath is not used but required to be defined
    srcPath = fullfile(matlabroot, 'toolbox', 'shared', 'testmeas', 'src', 'tammex');
    hdrPath = fullfile(matlabroot, 'toolbox', 'shared', 'testmeas', 'src', 'tammex');
    includePaths = {hdrPath};
    
  otherwise
    % Not specifying productStr is preferred, but it means that each client
    % must prepend header and source paths to each header and source file.
    srcPath = '';
    hdrPath = '';
    includePaths = {};
    
end % switch

end % getProductSpecificPaths

function [linkFlags, sysLinkFlags] = separateLinkAndSysFlags(productStr, linkFlags)
% Gather all system library link flags (i.e., -lm or -ldl). These should be 
% added to the end of the build command
    
    sysLinkFlags = {};
    if ismember(productStr, ...
            {'audio', 'dspblks', 'shared_dspvision', ...
            'shared_dspvision_mmio', 'shared_dspblks', ...
            'dsp_ml_core'})
        if iscell(linkFlags)
            for idx = 1:length(linkFlags)
                if ismember(linkFlags{idx}, {'-lm', '-ldl'})
                    sysLinkFlags{end+1} = linkFlags{idx}; %#ok
                end
            end
        end
    end
    linkFlags = setdiff(linkFlags, sysLinkFlags, 'stable');
end

function files = findNonBuildFiles(files)
% Look for files with an absolute path, path relative to MATLABROOT, or a
% path relative to the MATLABROOT/bin/ARCH directory.
    for i=1:length(files)
        filename1 = files{i};
        filename2 = fullfile(matlabroot, files{i});
        filename3 = fullfile(matlabroot, 'bin', computer('arch'), files{i});
        if exist(filename1, 'file')
            files{i} = filename1;
        elseif exist(filename2, 'file')
            files{i} = filename2;
        elseif exist(filename3, 'file')
            files{i} = filename3;
        else
            warning(message('dspshared:dspModifyBuildInfo:fileNotFound', filename1));            
        end
    end
end

function out = createCell(in)
% Create a cell from the input.
% The input is a (possibly empty) string if we were called from TLC,
% in which case we need to wrap it in a cell array.
if isempty(in)
  out = {};
elseif ischar(in)
  out = {in};
else
  out = in;
end
end


% =========================================================================

% LocalWords:  dspblks vipblks imaqblks imaq dspvision mmio Defs iso
% LocalWords:  dspextern visionrt visionio vntblks vnt scanutil
