classdef (Hidden = true) SectionTraceInfo < handle
%

%   Copyright 2011-2015 The MathWorks, Inc.
    
    properties (Access=private)
        FilePaths;
        FileNames;
        LineNumbers;
        FileIdxForLineNumbers;
        CodeSectionName;
        PrimaryCallSiteName;
        PrimaryCallSiteSID;
        ResolvedCallSiteSids = {};
        CallSiteNames;
        CallSiteSids;
        Checksum;
        BuildDir;
        OriginalModelRef;
        IsTask;
        SampleTime;
        EntityName;
        Tooltip;
    end
    
    methods (Access=private)        
        
        function updateNameAndTooltip(this)
            
            if isempty(this.EntityName)

                lCallSiteName = getPrimaryCallSiteName(this);
                lPrimaryCallSiteSid = '';
                if ~isempty(lCallSiteName)
                    this.EntityName = lCallSiteName;
                    lPrimaryCallSiteSid = getPrimaryCallSiteSID(this);
                else              
                    this.EntityName = getCodeSectionName(this);
                end
                
                this.Tooltip = lPrimaryCallSiteSid;

            end
        end
    end    
        
    methods (Access = public, Static=true, Hidden=true)
        
        function checksum = evaluateChecksum(buildDir)
            
            checksum = coder.profile.ProbeComponentRegistry...
                .getTraceabilityChecksumForBuildDir(buildDir);
            
        end
        
    end
    
    methods (Access = public, Hidden=true)
        
        function resolveCallSites(this, section, lTraceabilityHelper) 
            
            if isempty(this.CallSiteSids)
                if isTask(this)
                    rootComponent = getOriginalModelRef(this);
                    lResolvedCallSiteSIDs = {rootComponent};
                else
                    lResolvedCallSiteSIDs = {};
                end                    
            elseif length(this.CallSiteSids)==1
                lResolvedCallSiteSIDs = this.CallSiteSids;
            else
                
                % Filter out call sites where the name doesn't match the 
                % primary call site name.
                lResolvedCallSiteIdx = strcmp...
                    (this.PrimaryCallSiteName, this.CallSiteNames);
                assert(length(lResolvedCallSiteIdx)==length(this.CallSiteSids),...
                       'Number of call site names must match number of SIDs');
                   
                lResolvedCallSiteSIDs = getFeasibleCallSiteSIDs...
                    (lTraceabilityHelper, section, this.CallSiteSids(lResolvedCallSiteIdx));
                
            end     
            this.ResolvedCallSiteSids = lResolvedCallSiteSIDs;
        end
        
        
        function lResolvesToPrimaryCallSite = getResolvesToPrimaryCallSite(this)
            
            lResolvedCallSiteSIDs = getCallSiteSids(this);
            lResolvesToPrimaryCallSite = length(lResolvedCallSiteSIDs)==1;

        end
    

        
        function lName = getName(this)
            
            if this.isTask
                lName = this.CodeSectionName;
            else
                updateNameAndTooltip(this);
                lName = this.EntityName;
            end
                
        end
        
        function lTooltip = getTooltip(this)
            updateNameAndTooltip(this);
            lTooltip = this.Tooltip;
        end
        
        function this = SectionTraceInfo(lFileNames, lPaths, ...
                                       lSrcFileIdx, lLineNumbersIdx, ...
                                       lProfiledCodeName, ...
                                       ~, ~, ...
                                       lCallSiteNames, lCallSiteSids, ...
                                       lChecksum, buildDir, ...
                                       lOriginalModelRef, ...
                                       lIsTask,...
                                       lSampleTime)

            this.FileNames = lFileNames;
            this.FilePaths = lPaths;
            this.FileIdxForLineNumbers = lSrcFileIdx;
            this.LineNumbers = lLineNumbersIdx;
            this.CodeSectionName = lProfiledCodeName;
            if ~isempty(lCallSiteNames)
                this.PrimaryCallSiteName = lCallSiteNames{1};
            end
            if ~isempty(lCallSiteSids)
                this.PrimaryCallSiteSID = lCallSiteSids{1};
            else
                this.PrimaryCallSiteSID = '';
            end
            this.CallSiteNames = lCallSiteNames;
            this.CallSiteSids = lCallSiteSids;
            this.Checksum = lChecksum;
            this.BuildDir = buildDir;
            this.OriginalModelRef = lOriginalModelRef;
            this.IsTask = lIsTask;
            this.SampleTime = lSampleTime;
        end 
        
        function lIsTask = isTask(this)
            lIsTask = this.IsTask;
        end
        
        function lSampleTime = getSampleTime(this)
            lSampleTime = this.SampleTime;
        end
        
        function sid = getPrimaryCallSiteName(this)
            
            sid = this.PrimaryCallSiteName;
            
        end
        
        function sid = getPrimaryCallSiteSID(this)
            
            if getResolvesToPrimaryCallSite(this)
                resolvedCallSiteSids = getCallSiteSids(this);
                sid = resolvedCallSiteSids{1};
            else
                sid = this.PrimaryCallSiteSID;
            end
            
        end
        
        function sids = getUnresolvedCallSiteSids(this)
            
            sids = this.CallSiteSids;
            if isempty(sids)
                sids = {this.OriginalModelRef};
            end

        end
        
        function sids = getCallSiteSids(this) 
            sids = this.ResolvedCallSiteSids;
        end
        
        
        function tag = getCodeSectionName(this)
            
            tag = this.CodeSectionName;
            
        end
        
        function lOriginalModelRef = getOriginalModelRef(this)
            
            lOriginalModelRef = this.OriginalModelRef;
            
        end
        
        function name = getOriginalModelName(this)
            
            modelRef = this.OriginalModelRef;
            if any(strfind(modelRef, ':'))
                % Code section, right-click build
                name = strtok(modelRef, ':');
            elseif any(strfind(modelRef, '/'))
                % Task section, right-click build
                name = strtok(modelRef, '/');
            else
                % Plain model name
                name = modelRef;
            end
        end
        
        function buildDir = getBuildDir(this)
            
            buildDir = this.BuildDir;
            
        end
        
        function lChecksum = getStoredChecksum(this)
            
            lChecksum = this.Checksum;
            
        end
        
        function sites = getCallSiteNames(this)
            
            sites = this.CallSiteNames;
            
        end
        
        function files = getFileNames(this)
            
            files = this.FileNames;
            
        end
        
        function filePaths = getFilePaths(this)
            
            filePaths = this.FilePaths;
            
        end
        
        function lineNumbers = getLineNumbers(this)
            
            lineNumbers = cell(size(this.FilePaths));
            
            for i=1:length(lineNumbers)
                idx = this.FileIdxForLineNumbers==i;
                lineNumbers{i} = this.LineNumbers(idx);
            end
            
        end
    end
end
