%

% Copyright 2016 The MathWorks, Inc.

% PILTest: Base class for MLPILTest and SLPILTest classes which implement
% a class based PIL API unit test for the MATLAB Coder and Simulink Coder
% workflows

classdef PILTest < matlab.unittest.TestCase
    properties (SetAccess = protected, GetAccess = protected)
        
        % PIL Configuration for MATLAB or Simulink Coder PIL workflows
        Config;
        
        % Optional: Test Points to run for MATLAB or Simulink Coder PIL
        % workflows. Default value 'All'
        TestPoint;
        
        % Optional: Additional configuration parameters to
        ConfigParams;

    end

    properties (SetAccess = protected, GetAccess = protected)
        testparams;
    end

    methods
        function result = testRunner(test)
            switch test.TestPoint
                case 'All'
                    result = test.run;
                otherwise
                    result = test.run(test.TestPoint);
            end
        end
    end
        
    methods(TestClassSetup)
        function classSetupPILTest(test)           
            workingDir = 'piltest';
            origDir = pwd;
                        
            if(exist(workingDir, 'dir') == 7)
                [success, msg, msgID] = rmdir(workingDir, 's');
                if ~success
                    error(msgID, '%s', msg);
                end
            end
                                    
            test.addTeardown(@()cd(origDir));
            iCreateDir(test, workingDir);
            cd(workingDir);
            
            % Add current folder to path. sl_customization.m or rtwTargetInfo
            % can be located in the current folder
            origPath = addpath(origDir);
            % Add '/piltest' subfolder to path. The piltest folder will contain 
            % the test models/functions and needs to be on the path so that
            % the models/functions are visible from the test-point
            % subfolders.
            addpath(fullfile(origDir, 'piltest'));
            test.addTeardown(@()path(origPath));
                        
            % Copy testmodels or testfunctions to [workingDir ,'/piltest'] folder
            iCopyTestFiles(test);
        end
    end
    
    methods(Access = protected)    
        function inputParserPILTest(test, Config, varargin)
            p = inputParser;
            
            addParameter(p, 'ConfigParams', {}, @iscell);
            addParameter(p, 'TestPoint', 'All', ...
                    @(x) any(validatestring(x,test.testparams.ExpectedTestPoints)));
                        
            parse(p, varargin{:});
            parserResults = p.Results;
            
            test.Config = Config;
            
            propName = {'ConfigParams', 'TestPoint'};
            for i = 1:length(propName)
                test.(propName{i}) = parserResults.(propName{i});
            end
        end                        
        
        function iCreateDir(~, WorkingDir)
            [success, msg, msgID] = mkdir(WorkingDir);
            if ~success
                error(msgID, '%s', msg);
            end
        end
        
        function iSetupTestPointFolder(test, testpoint)            
            origFolder = pwd;
            test.addTeardown(@(x)cd(origFolder));
            if ( ~(exist(testpoint, 'dir') == 7) )
                iCreateDir(test, testpoint);
            end
            cd(testpoint);
        end
        
        function iSetupSubFolder(test, FolderName)
            origFolder = pwd;
            codeInterfaceFolder = regexprep(FolderName,'[\s]','');
            iCreateDir(test, codeInterfaceFolder);
            cd(codeInterfaceFolder);
            test.addTeardown(@(x)cd(origFolder));
        end
        
        function iCopyTestFiles(test)            
            [success, msg, msgID] = copyfile(test.testparams.TestFileLoc,pwd,'f');
            
            if ~success
                error(msgID, '%s', msg);
            end
        end  
        
        function iClearLocalMEXFilesFromMemory(test)            
            % 1) Find all mex files in subfolder
            % 2) Add teardown to remove them
            dirName = pwd;
            mexFiles = dir(fullfile(dirName, ['*.', mexext]));

            for i=1:numel(mexFiles)
                clearStr = sprintf('clear %s',  ...
                    fullfile(mexFiles(i).folder, mexFiles(i).name ));
                test.addTeardown(@()evalin('base', clearStr));
            end            
        end
        
        function iPrintTestPointStart(~, testpoint)            
            msg = DAStudio.message('Connectivity:piltest:StartTestPoint', ...
                testpoint);
            fprintf('\n### %s\n',msg);            
        end
        
        function iPrintTestPointEnd(~, testpoint)            
            msg = DAStudio.message('Connectivity:piltest:EndTestPoint', ...
                testpoint);
            fprintf('\n### %s\n',msg);            
        end
        
        
    end
end
