function existingSharedCodeDiagnostic...
    (lExistingSharedCode, lSharedUtilsFolder, ...
     lUseOnlyExistingSharedCode,...
     lModelName, newLocallyGeneratedFiles, constParamsUpdatedLocally)

%EXISTINGSHAREDCODEDIAGNOSTIC check compliance with setting of UseOnlyExistingSharedCode

% Copyright 2016-2020 The MathWorks, Inc.

if strcmp(lUseOnlyExistingSharedCode, 'none')
    % The diagnostic UseOnlyExistingSharedCode is set none, so no diagnostics to
    % perform
    return;
end

lResolvedFiles = coder.internal.xrel.ResolvedFiles(lSharedUtilsFolder);
[srcFilesLocal, lResolveStatus, ~, srcFilesNotSupported] = ...
    getResolveStatus(lResolvedFiles);

notReplacedIdx = ...
    lResolveStatus~=coder.internal.xrel.FileResolveStatus.Repository;
srcFilesNotReplaced = srcFilesLocal(notReplacedIdx);

% Utility files to support non-finite are currently not registered
% Shared Code Manager; these files will never be replaced
srcFilesNotReplaced = [srcFilesNotReplaced(:); srcFilesNotSupported(:)];

% If the const_params file was updated locally, for diagnostic purposes we
% consider that it was not replaced with existing shared code
srcFilesNotReplaced = [srcFilesNotReplaced(:); constParamsUpdatedLocally];

if isempty(srcFilesNotReplaced)
    return;
end

fileListWithModelLinks = i_getFileListWithModelLinks...
    (lResolvedFiles, srcFilesNotReplaced);
fileListWithModelLinks = DAStudio.message...
    ('coder_xrel:crossRelease:FilesNotInExistingArea', ...
     lExistingSharedCode, fileListWithModelLinks);

% If the diagnostic is set to error, remove any locally generated files from the
% the current build
if strcmp(lUseOnlyExistingSharedCode, 'error')
    for i=1:length(newLocallyGeneratedFiles)
        delete(fullfile(lSharedUtilsFolder, newLocallyGeneratedFiles{i}));
    end
end

switch(lUseOnlyExistingSharedCode)
  case 'warning'
    currentDiagTypeStr = DAStudio.message...
        ('coder_xrel:crossRelease:LocallyGeneratedDiagTypeWarn');
    proposedDiagTypeStr = DAStudio.message...
        ('coder_xrel:crossRelease:LocallyGeneratedDiagTypeNone');
    proposedDiagSetting = 'none';
    % Command to update existing shared code area
    updateCmd = sprintf...
        ('sharedCodeUpdate(''%s'', ''%s'')', ...
         lSharedUtilsFolder, lExistingSharedCode);
    updateCmdLink = sprintf('<a href="matlab:%s">%s</a>', updateCmd, updateCmd);
    msgAddMissingFiles = DAStudio.message...
        ('coder_xrel:crossRelease:AddMissingFilesWarn', updateCmdLink);
  otherwise % error
    currentDiagTypeStr = DAStudio.message...
        ('coder_xrel:crossRelease:LocallyGeneratedDiagTypeError');
    proposedDiagTypeStr = DAStudio.message...
        ('coder_xrel:crossRelease:LocallyGeneratedDiagTypeWarn');
    proposedDiagSetting = 'warning';
    % Instructions to update existing shared code area
    msgAddMissingFiles = DAStudio.message...
        ('coder_xrel:crossRelease:AddMissingFilesError');
end

% Command to lower the diagnostic setting
fixModelCmd = sprintf...
    ('set_param(''%s'', ''UseOnlyExistingSharedCode'', ''%s'')', ...
     lModelName, proposedDiagSetting);
fixModelCmdLink = sprintf('<a href="matlab:%s">%s</a>', ...
                          fixModelCmd, fixModelCmd);

% Part of the diagnostic message is the same for warning or error
diagnosticParamName = 'UseOnlyExistingSharedCode';
msgShared = DAStudio.message...
    ('coder_xrel:crossRelease:LocallyGeneratedDiagnostic',...
     fileListWithModelLinks, currentDiagTypeStr, ...
     diagnosticParamName, currentDiagTypeStr, ...
     proposedDiagTypeStr, fixModelCmdLink, ...
     msgAddMissingFiles);

switch(lUseOnlyExistingSharedCode)
    case 'warning'
        exc = MSLException([], ...
            message('coder_xrel:crossRelease:LocallyGeneratedDiagWarn', ...
            msgShared));
        sldiagviewer.reportWarning(exc);
    otherwise % error
        exc = MSLException([], ...
            message('coder_xrel:crossRelease:LocallyGeneratedDiagError', ...
            msgShared));
        throw(exc);
end


function fileListWithModelLinks = i_getFileListWithModelLinks...
    (lResolvedFiles, srcFilesNotReplaced)
% Return a string that displays as a list of shared source files with associated
% hyperlinks to the blocks responsible for generating those files

% Get model traceability from Shared Code Manager
[allSCMSrcFiles, ~, ~, allTraceability] = getSCMData(lResolvedFiles);
[~, ~, ib] = intersect(srcFilesNotReplaced, allSCMSrcFiles);
traceabilityNotReplaced = allTraceability(ib);
allSCMSrcFilesNotReplaced = allSCMSrcFiles(ib);

fileListWithModelLinks = '';
for i=1:length(allSCMSrcFilesNotReplaced)
    srcFile = allSCMSrcFilesNotReplaced{i};
    traceabilityLinks = '';
    traceability = traceabilityNotReplaced{i};
    separator = '';
    for ii2=1:length(traceability)
        sid = traceability{ii2};
        cmd = sprintf('hilite_system(''%s'')', sid);
        cmdHtml = sprintf('<a href="matlab:%s">%s</a>', cmd, sid);
        traceabilityLinks = sprintf...
            ('%s%s%s', traceabilityLinks, separator, cmdHtml);
        separator = ', ';
    end
    if ~isempty(traceabilityLinks)
        traceabilityLinks = sprintf(' (%s)', traceabilityLinks);
    end
    srcFileStr = sprintf('\n    %s%s', srcFile, traceabilityLinks);
    fileListWithModelLinks = [fileListWithModelLinks srcFileStr]; %#ok<AGROW>
end
