% TaskWarnings - Used for formatting the warning messages in the Task display

% Copyright 2015-2020 The MathWorks, Inc.

classdef TaskWarnings < parallel.internal.display.DisplayableItem & ...
        parallel.internal.display.StackDisplayMixin
    properties (SetAccess = immutable, GetAccess = private)
        Warnings
        Parent
        Task
    end

    methods (Access = protected)
        function list = listAttachedFilesAndPaths(obj)
            list = [obj.Parent.AttachedFiles; obj.Parent.AdditionalPaths];
        end
    end

    methods
        function obj = TaskWarnings(displayHelper, warnings, task)
            obj@parallel.internal.display.DisplayableItem(displayHelper);
            obj.Warnings = warnings;
            obj.Parent = task.Parent;
            obj.Task = task;
        end

        function displayInMATLAB(obj, ~)
            import parallel.internal.display.DisplayableItem

            if isempty(obj.Warnings)
                msg = message('MATLAB:parallel:display:None');
                displayValue = msg.getString();
                obj.DisplayHelper.displayProperty('Warnings', displayValue, ...
                    DisplayableItem.DoNotFormatValue);
                return
            elseif numel(obj.Warnings) == 1
                % There's only one warning, so display its message (wrapped).
                warningMessage = obj.DisplayHelper.wrapText(obj.Warnings.message);
                warningMessage = obj.DisplayHelper.formatCellStr(warningMessage);
                obj.DisplayHelper.displayProperty('Warnings', warningMessage, ...
                    DisplayableItem.DoNotFormatValue);

                if isempty(obj.Warnings.stack)
                    return;
                end

                stackString = getStackCellStr(obj, obj.Warnings.stack, ...
                    obj.DisplayHelper.ShowLinks);
                stack = obj.DisplayHelper.formatCellStr(stackString);
                obj.DisplayHelper.displayProperty('Warning Stack', ...
                                                  stack, ...
                                                  DisplayableItem.DoNotFormatValue);  
            else
                if obj.DisplayHelper.ShowLinks
                    % If there's more than one warning we display a clickable
                    % link, which displays the warnings when clicked.
                    warningMessage = message('parallel:job:ListWarningsLinkText');
                    displayValue = warningMessage.getString();
                    link = obj.hGetLink(displayValue);
                    obj.DisplayHelper.displayProperty('Warnings', link);
                else
                    % Just revert to default MATLAB display in this case.
                    displayValue = obj.Warnings;
                    obj.DisplayHelper.displayProperty('Warnings', displayValue);
                end
            end

        end
    end

    methods ( Hidden )
        function link = hGetLink(obj, displayValue)
            matlabFunction = sprintf('parallel.internal.display.TaskWarnings.displayWarnings(''%s'')', ...
                serialize(parallel.internal.display.TaskMemento.createFromTask(obj.Task)));
            link = parallel.internal.display.HTMLDisplayType(displayValue, matlabFunction);
        end
    end

    methods ( Access = private )
        function vectorDisplayWarnings(obj)
            % Make a list of strings from the warnings issued in the task
            warningsList = parallel.internal.display.DisplayHelper.formatWarningsList(obj.Warnings);

            warningsMessage = message('parallel:job:WarningsDuringTaskExecution', obj.Task.ID, warningsList).getString();

            % Use the internal printWrapped function to print a warning wrapped to the
            % command window size.
            matlab.internal.display.printWrapped(warningsMessage);
        end
    end

    methods ( Static )
        function displayWarnings( serializedMemento )
            import parallel.internal.display.DisplayHelper

            % Firstly try to recreate the task object to get and
            % display its warnings.
            task = createObjectFromMemento(...
                parallel.internal.display.Memento.deserialize(serializedMemento));

            % We use the display helper to format the table display
            % for the vector of task warnings.
            helper = DisplayHelper(length('identifier'));
            warnings = task.Warnings;
            warningDisplayer = parallel.internal.display.TaskWarnings(helper, warnings, task);
            warningDisplayer.vectorDisplayWarnings();
        end
    end
end
