classdef (Hidden) SILPILFixits < handle
%SILPILFIXITS utility class to manage SIL/PIL fix-it actions
%
%   This is an undocumented class. Its methods and properties are likely to
%   change without warning from one release to the next.

%   Copyright 2018-2019 The MathWorks, Inc.
    
    methods(Static, Access = public)
        
        function actionsPerformed = fix(action, varargin)
            % fix action entry point
            import rtw.pil.SILPILFixits
            
            switch action
                case 'HostComputerProd'
                    callback = @SILPILFixits.setHostComputerProd;
                case 'PWS'
                    callback = @SILPILFixits.setPWS;
                case 'LongLong'
                    callback = @SILPILFixits.enableLongLong;
                case 'NonFinite'
                    callback = @SILPILFixits.disableNonFinite;
                case 'STIndependent'
                    callback = @SILPILFixits.setSTIndependent;
                case 'MATFileLogging'
                    callback = @SILPILFixits.disableMATFileLogging;
                otherwise
                    assert(false, 'Unknown fixit action: %s', action);
            end
            actionsPerformed = callback(varargin{:});
        end
        
        function actionsPerformed = fixTargetEnvironmentSubfolder
            Simulink.fileGenControl('set', 'CodeGenFolderStructure', Simulink.filegen.CodeGenFolderStructure.TargetEnvironmentSubfolder);
            msg = message('PIL:pil_subsystem:FolderStructureActionPerformed');
            actionsPerformed = msg.getString;
        end
        
        function actionsPerformed = fixHarnessSTFAndHardware(harness, stf, hw)
            paramValArray = { ...
                {'SystemTargetFile', stf}, ...
                {'TargetHWDeviceType', hw}};
            actionsPerformed = rtw.pil.SILPILFixits.setParam(harness, paramValArray);
        end
    end
    
    
    methods(Static, Access = private)
        
        function actionsPerformed = setHostComputerProd(varargin)
            % Host prod hardware: set ProdEqTarget on and PWS off
            % Also need to set long long mode, which is off by default
            componentName = varargin{1};
            host = rtwhostwordlengths;
            hostLongLongModeVal = host.LongLongMode;
            if hostLongLongModeVal
                hostLongLongMode = 'on';
            else
                hostLongLongMode = 'off';
            end
            paramValArray = { ...
                {'ProdEqTarget', 'on'}, ...
                {'PortableWordSizes', 'off'}, ...
                {'ProdHWDeviceType', rtw.pil.ModelBlockPIL.getHostProdHW}, ...
                {'ProdLongLongMode', hostLongLongMode}};
            
            actionsPerformed = rtw.pil.SILPILFixits.setParam(componentName, paramValArray);
        end
        
        function actionsPerformed = setPWS(varargin)
            % special handling for Windows64 which is the default
            % hardware implementation and requires long long to be
            % enabled in order for uint64 (corresponding to native
            % word size) to get typedef'd in rtwtypes.h
            componentName = varargin{1};
            paramValArray = { ...
                {'ProdEqTarget', 'on'}, ...
                {'PortableWordSizes', 'on'}};
            if rtw.pil.ModelBlockPIL.getPWSEnableLongLong(componentName)
                paramValArray = [paramValArray ...
                    {{'ProdLongLongMode', 'on'}}];
            end
            actionsPerformed = rtw.pil.SILPILFixits.setParam(componentName, paramValArray);
        end
        
        function actionsPerformed = enableLongLong(varargin)
            % enable longlongMode on 'production' or 'target' hardware
            componentName = varargin{1};
            prefix = varargin{2};
            paramValArray = {{[prefix 'LongLongMode'], 'on'}};
            actionsPerformed = ...
                rtw.pil.SILPILFixits.setParam(componentName, paramValArray);
        end
        
        function actionsPerformed = setSTIndependent(varargin)
            % set Ensure sample time independent
            componentName = varargin{1};
            paramValArray = {{'SampleTimeConstraint', 'STIndependent'}};
            actionsPerformed = ...
                rtw.pil.SILPILFixits.setParam(componentName, paramValArray);
        end
        
        function actionsPerformed = disableNonFinite(varargin)
            % set SupportNonFinite to off
            componentName = varargin{1};
            paramValArray = {{'SupportNonFinite', 'off'}};
            actionsPerformed = ...
                rtw.pil.SILPILFixits.setParam(componentName, paramValArray);
        end
        
        function actionsPerformed = disableMATFileLogging(varargin)
            % set MATFileLogging to off
            componentName = varargin{1};
            paramValArray = {{'MatFileLogging', 'off'}};
            actionsPerformed = ...
                rtw.pil.SILPILFixits.setParam(componentName, paramValArray);
        end
        
        
        
        function actionsPerformed = setParam(componentName, paramValArray)
            actionsPerformed = cell(1, numel(paramValArray));
            for idx =1:numel(paramValArray)
                param = paramValArray{idx}{1};
                value = paramValArray{idx}{2};
                actionsPerformed{idx} = configset.internal.fixIt(componentName, param, value, true);
            end
            actionsPerformed = strjoin([{''} actionsPerformed], '\n');
        end
    end
end
