% JobStatusData - Static information about a job's state

% Copyright 2020 The MathWorks, Inc.

classdef JobStatusData < handle
    
    properties (SetAccess = immutable, GetAccess = private)
        ID
        RawJobType
        Username
        CreateTime
        SubmitTime
        FinishTime
        State
        TotalPendingTasks
        TotalRunningTasks
        TotalFinishedTasks
        TotalTasks
        Tag
        ApiTag
        TotalSuccessfulFinishedTasks
        TaskIDsWithErrors
        TaskIDsWithWarnings
        FirstTaskMLFunctionName
        CorruptionInfo
    end
    
    methods
        function obj = JobStatusData(id, jobType, username, ...
            createTime, submitTime, finishTime, state, ...
            totalPendingTasks, totalRunningTasks, totalFinishedTasks, totalTasks, ...
            tag, apiTag, totalSuccessfulFinishedTasks, taskIDsWithErrors, taskIDsWithWarnings, ...
            firstTaskMLFunctionName, corruptionInfo)
        
            % A no-arg constructor represents an empty job status data
            if nargin == 0
                return
            end
            
            obj.ID = id;
            obj.RawJobType = jobType;
            obj.Username = username;
            obj.CreateTime = createTime;
            obj.SubmitTime = submitTime;
            obj.FinishTime = finishTime;
            obj.State = state;
            obj.TotalPendingTasks = totalPendingTasks;
            obj.TotalRunningTasks = totalRunningTasks;
            obj.TotalFinishedTasks = totalFinishedTasks;
            obj.TotalTasks = totalTasks;
            obj.Tag = tag;
            obj.ApiTag = apiTag;
            obj.TotalSuccessfulFinishedTasks = totalSuccessfulFinishedTasks;
            obj.TaskIDsWithErrors = taskIDsWithErrors;
            obj.TaskIDsWithWarnings = taskIDsWithWarnings;
            obj.FirstTaskMLFunctionName = firstTaskMLFunctionName;
            obj.CorruptionInfo = corruptionInfo;
        end
        
        function tf = isempty(objOrObjs)
            tf = arrayfun(@(obj) isempty(obj.ID), objOrObjs);
        end
        
        function value = getId(obj)
            value = obj.ID;
        end
        
        function value = getRawJobType(obj)
            value = obj.RawJobType;
        end
        
        function value = getJobType(obj, userMatch)
            import parallel.internal.cluster.BatchJobConstants
            import parallel.internal.cluster.ParpoolJobConstants
            import parallel.internal.cluster.types.JobType
            
            if BatchJobConstants.isBatchFunctionJob(obj.FirstTaskMLFunctionName, obj.ApiTag)
                value = JobType.BatchJobOnFuntion;
            elseif BatchJobConstants.isBatchScriptJob(obj.FirstTaskMLFunctionName, obj.ApiTag)
                value = JobType.BatchJobOnScript;
            elseif ParpoolJobConstants.isParpoolJob(obj.ApiTag)
                if userMatch && strcmp(obj.State, parallel.internal.types.States.Running.Name)
                    value = JobType.CurrentInteractiveMATLABPool;
                else
                    value = JobType.MATLABPool;
                end
            else
                value = obj.RawJobType;
            end
        end
        
        function value = getUsername(obj)
            value = obj.Username;
        end
        
        function value = getCreateTime(obj)
            value = obj.CreateTime;
        end
        
        function value = getSubmitTime(obj)
            value = obj.SubmitTime;
        end
        
        function value = getFinishTime(obj)
            value = obj.FinishTime;
        end
        
        function value = getState(obj)
            value = obj.State;
        end
        
        function value = getTotalPendingTasks(obj)
            value = obj.TotalPendingTasks;
        end
        
        function value = getTotalRunningTasks(obj)
            value = obj.TotalRunningTasks;
        end
        
        function value = getTotalFinishedTasks(obj)
            value = obj.TotalFinishedTasks;
        end
        
        function value = getTotalTasks(obj)
            value = obj.TotalTasks;
        end
        
        function value = getTag(obj)
            value = obj.Tag;
        end
        
        function value = getApiTag(obj)
            value = obj.ApiTag;
        end
        
        function value = getTotalSuccessfulFinishedTasks(obj)
            value = obj.TotalSuccessfulFinishedTasks;
        end
        
        function value = getNumTasksWithErrors(obj)
            value = numel(obj.TaskIDsWithErrors);
        end
        
        function value = getTaskIdsWithErrors(obj)
            value = obj.TaskIDsWithErrors;
        end
        
        function value = getNumTasksWithWarnings(obj)
            value = numel(obj.TaskIDsWithWarnings);
        end
        
        function value = getTaskIdsWithWarnings(obj)
            value = obj.TaskIDsWithWarnings;
        end
        
        function value = getFirstTaskMLFunctionName(obj)
            value = obj.FirstTaskMLFunctionName;
        end
        
        function value = getCorruptionInfo(obj)
            value = obj.CorruptionInfo;
        end
        
        function value = isFinished(obj)
            value = strcmp(obj.State, parallel.internal.types.States.Finished.Name);
        end
        
        function value = getDescription(obj, userMatch)
            % Use the tag if the user has set it, otherwise use the default
            % description for the job type
            if ~strcmp(obj.ApiTag, obj.Tag) && ~isempty(obj.Tag)
                value = obj.Tag;
            else
                jobType = obj.getJobType(userMatch);
                value = jobType.Description;
            end
        end
    end
end
