function sldvsharecallback(method,objH,source,msg,msgid,varargin)
% Notification gateway called from Simulink and Stateflow for SLDV

% Copyright 2005-2023 The MathWorks, Inc.

    if nargin<6
        varargin = ''; 
    end
    
    if nargin<5
        msgid = '';
    end

    if nargin<4
        msg = '';
    end
    
    if nargin<3
        source = 'simulink';
    end
    
    if nargin<2
        error(message('Sldv:CallBack:ArgNum'));
    end

    switch(method)
    case {'unsupported','unsupportedremcurrent'}                       
        if objH==0
            objH=18;
        end
        
        if strcmp(source, 'sldv_stubbed')
            % g1634170: sldv_stubbed is called as a 'source' from the
            % clients like PLCUtils.cpp, sl_utils.hpp. Here, an ID is
            % attached to the warning since no IDs are sent by the
            % clients.
            msgid = 'Sldv:Compatibility:UnsupportedFcn';
        elseif strcmp(source, 'analysis_error')
            msgid = 'Sldv:SldvRun:ErrorDuringAnalysis';
            source = 'sldv';
        end
        
        if strcmp(method,'unsupported')
            avtcgirunsupcollect('push',objH,source,msg,msgid);
        else
            avtcgirunsupcollect('pushremcurrent',objH,source,msg,msgid);
        end
        
    case 'postLoad'
    case 'init'
    case 'start'
    case 'stop'
    case 'preSave'
        % Ignore saving when an analysis is running
        try
            activeTC = Sldv.Token.get.getTestComponent;
        catch Mex   %#ok<*NASGU>
            activeTC = [];
        end
        analysisRunning = false;
        if ~isempty(activeTC)
            try 
                analysisObj = get_param(activeTC.analysisInfo.designModelH,'Handle');
            catch Mex
                analysisObj = 0;
            end
            analysisRunning = ((activeTC.analysisInfo.analyzedModelH == objH) || ...
                               (analysisObj == objH));
        end
        
        if ~analysisRunning
            % Only close results if the model name has changed
            close_results(objH, true);
        else
            objpath = getfullname(objH);
        end
        
    case {'close', 'forceClose'}
        close_results(objH, false);
    case {'unknown','open'}    
    otherwise
        error(message('Sldv:CallBack:NotificationType'));
    end
end


function close_results(modelH, detectNameChange)
    % detectNameChange is set to true when we care about the save operation
    % and whether it does change the name of the model
    % for close operations, we don't care to detect the name change
    try
        handles = get_param(modelH, 'AutoVerifyData');
    catch Mex
        handles = [];
    end
    
    ModelOperations = struct("SAVE", "save", ...
                             "SAVEAS", "saveas", ...
                             "CLOSE", "close");
    
    currentOperation = ModelOperations.CLOSE;
    
    if ~isempty(handles) && detectNameChange
        if isfield(handles, 'modelName')
            if strcmp(handles.modelName, get_param(modelH, 'Name'))
                % name hasn't changed; regular save operation
                % no need to change anything
                currentOperation = ModelOperations.SAVE;
            else
                % name has changed; a save-as operation
                % session needs to be reset and other close operations need to
                % proceed
                currentOperation = ModelOperations.SAVEAS;
            end
        else
            % the modelName field in AutoVerifyData can be absent if the
            %  model never ran an analysis in the current MATLAB session
            % but if the SLDV toolstrip was open, there will be a
            %  session object and AutoVerifyData will be populated with it
            % treat this as a regular save operation
            currentOperation = ModelOperations.SAVE;
        end
    end
    
    % If we couldn't find AutoVerifyData or if it was just save, don't change
    % anything
    if ~isempty(handles) && currentOperation ~= ModelOperations.SAVE
        % Check if Sldv.DebugService object is alive (Feature: Slicer on-ramp)
        % If yes, delete it
        if isfield(handles, 'DebugService')
            debugService = handles.DebugService;
            if ~isempty(debugService)
                delete(debugService);
            end
        end

        % Check, if any Sldv.Session object is alive (Feature: BackgroundAnalysis)
        if isfield(handles, 'sldvSession')
            session = handles.sldvSession;
            if ~isempty(session) && isvalid(session)
                % Terminate the session, if analysis is running so that the ongoing analysis also gets
                % terminated
                if session.isAnalysisRunning()
                    terminate(session);
                end
                if currentOperation == ModelOperations.CLOSE
                    % only for close, we delete the session
                    delete(session);
                elseif currentOperation == ModelOperations.SAVEAS
                    % for save-as, we reset the session
                    session.reset([], [], true, []);
                    % also reset stored results on the SLDV toolstrip,
                    %  if open
                    Sldv.ui.toolstrip.internal.resettoolstrip(modelH);
                end
            end
        end

        % Set 'AutoVerifyData' to 'empty' only after Sldv.Session is terminated/deleted/reset.
        % If Sldv.Session terminated while analysis is still ongoing, then it also terminates the ongoing
        % analysis. And the analysis termination method calls slavteng_* callback function, which in turn
        % calls 'drawnow' if 'AutoVerifyData' is found empty; which can lead to undesired behavior during
        % termination of Sldv.Session.
        set_param(modelH, 'AutoVerifyData', []);

        if isfield(handles, 'modelView') && ~isempty(handles.modelView)
            delete(handles.modelView);
        end

        % Close SLDV Progress UI, if it is open
        if isfield(handles, 'ui') && isvalid(handles.ui)
            delete(handles.ui);
        end

        % Close SLDV Results Summary UI, if it is open (Geck - g1212720)
        % TopTester: matlab/test/toolbox/sldv/sldv/mdladv/trunTimeErrorChecks.m -testspec:lvlTwo_tCheckIntegerOverflow_BasicComp
        if isfield(handles, 'res_dialog')
            res_dlg = handles.res_dialog;
            if ~isempty(res_dlg) && ishandle(res_dlg)
                res_dlg.delete();
            end
        end

        if isfield(handles, 'analysisFilter') && slavteng('feature', 'MultiFilter')
            filterExplorer = handles.analysisFilter;
            if ~isempty(filterExplorer)
                try
                    Sldv.FilterExplorer.close(filterExplorer);
                catch Mex
                end
            end
        end

        clear('handles');
        avtcgirunsupcollect('clear');
    end
end
