classdef DetailedReportManager < handle  % DetailedReportManager
    % Manages detailed reports associated with cvmodelview

    % Copyright 2019 The MathWorks, Inc.
    properties (Access = public)
        folderName = 'CoverageDetails';
        reportNamePattern = 'docked__cov__report__$MODEL$__$COVMODE$.html';
        topModel;
        reportSettings;
        generatedReports;
        reportFolder;
        covModes = {};
    end
    
    properties (GetAccess = public, SetAccess = private)
        hasMultipleCovModes = false;
    end
    
%% Public methods
    methods (Access = public)
        % constructor
        function this = DetailedReportManager(topModel, contextInfo)
            this.topModel = topModel;
            this.reportSettings = this.getReportSettings(contextInfo);
            this.reportFolder = this.getReportFolder();
            this.generatedReports = struct(...
                                'analyzedModel', {}, ...
                                'harnessModel', {}, ...
                                'ownerModel', {}, ...
                                'reportName', {}, ...
                                'reportPath', {}, ...
                                'reportPathEncoded', {}, ...
                                'covMode', {}, ...
                                'modelName', {}, ...
                                'ctxInfo',{});
        end
        
        function delete(~)
            % Currently, generated reports are not automatically deleted.
            % They may be overwritten in subsequent runs or if cov
            % highlighting is reapplied.
        end
        
        function createReport(this, allCovData)
            for idx = 1:numel(allCovData)
                cvd = allCovData(idx);
                simMode = cvd.simMode;
                covMode = SlCov.CovMode.toString(simMode);
                this.logCovMode(covMode);
                reportName = this.getReportName(cvd.modelinfo.analyzedModel, covMode);
                reportFullPath = fullfile(this.reportFolder, reportName);
                reportFullPath_encoded = fullfile(this.reportFolder, urlencode(reportName));
                cvhtml(reportFullPath, cvd, this.reportSettings, simMode, 'calledFromCvHTMLDataGroup');
                ctxInfo = this.reportSettings.contextInfo;
                modelName = '';
                if ~isempty(ctxInfo)
                    ctxInfo.cvdId =  cvd.id;
                    modelName = get_param(bdroot(cv('get', cv('get', cvd.rootId, '.topSlsf'), '.handle')), 'name');
                end
                report = struct('analyzedModel', cvd.modelinfo.analyzedModel, ...
                                'harnessModel', cvd.modelinfo.harnessModel, ...
                                'ownerModel', cvd.modelinfo.ownerModel, ...
                                'reportName', reportName, ...
                                'reportPath', reportFullPath, ...
                                'reportPathEncoded', reportFullPath_encoded, ...
                                'covMode', covMode,...
                                'modelName', modelName, ...
                                'ctxInfo', ctxInfo);
                            
                this.generatedReports(end + 1) = report;
            end
        end
        
        function report = getReport(this, modelName, covMode)
            idx = (strcmpi({this.generatedReports.analyzedModel}, modelName) | ...
                   strcmpi({this.generatedReports.harnessModel}, modelName) | ...
                   strcmpi({this.generatedReports.ownerModel}, modelName)) ...
                  & strcmp({this.generatedReports.covMode}, covMode);
            report = this.generatedReports(idx);
        end

        function modes = getCovModes(this)
            modes = this.covModes;
        end
    end
    
%% Private methods
    methods (Access = private)
        
        function logCovMode(this, covMode)
            if ~ismember(covMode, this.covModes)
                this.covModes{end+1} = covMode;
            end
            this.hasMultipleCovModes = (numel(this.covModes) > 1);
        end
        
        function name = getReportName(this, modelName, covMode)
            modelName = urlencode(modelName); % account for slashes
            name = this.reportNamePattern;
            name = strrep(name, '$MODEL$', modelName);
            name = strrep(name, '$COVMODE$', covMode);
        end
        
        function reportFolder = getReportFolder(this)
            covBaseDir = get_param(this.topModel, 'CovOutputDir');
            covBaseDir = strrep(covBaseDir, '$ModelName$', '');
            covBaseDir = cvi.TopModelCov.checkOutputDir(covBaseDir);
            reportFolder = fullfile(covBaseDir, this.folderName);

            if ~exist(reportFolder ,'dir')
                mkdir(reportFolder);
            end
        end
        
        function cvhtmlS = getReportSettings(this, contextInfo)
            cvhtmlS = cvi.CvhtmlSettings(this.topModel);
            cvhtmlS.showReport = false; 
            cvhtmlS.elimFullCovDetails = false;
            cvhtmlS.generateWebViewReport = false;
            cvhtmlS.reportSignalRange = false;
            cvhtmlS.contextInfo = contextInfo;
        end
    end
end



    

