classdef TargetInterface < handle
%

% Copyright 2013-2022 The MathWorks, Inc.
    properties (Access = private)
        SourceFileTargetInterface;
        HeaderFileTargetInterface;
    end
    
    properties (Access = protected)
        TargetWordSize;
        IdentifierCDataType;
        IdentifierTypeSize;
        SingleThreadTiming;
        ProfilingTimer;
        GlobalRegistry;
        CodeDescriptor
    end
    
    properties (SetAccess = public, GetAccess = private)
        TargetCollectDataFcnName;
    end
    
    methods
        function set.ProfilingTimer(this, lTimer)
            if isa(lTimer, 'coder.profile.Timer')
                % Backwards compatibility
                this.ProfilingTimer = coder.profile.private.TimerWrap(lTimer);
            else
                this.ProfilingTimer = lTimer;
            end
        end
    end
    
    methods (Access = public)
        function init (this, lTargetWordSize, lSingleThreadTiming, ...
                lProfilingTimer, lGlobalRegistry, codeDescriptor)
            arguments
                this
                lTargetWordSize
                lSingleThreadTiming
                lProfilingTimer
                lGlobalRegistry
                codeDescriptor = []
            end
        
            this.TargetWordSize = lTargetWordSize;
            
            this.IdentifierCDataType = ...
                coder.profile.ExecTimeConfig.getIdentifierCDataType...
                (lTargetWordSize, codeDescriptor);
            
            this.IdentifierTypeSize = ...
                coder.profile.ExecTimeConfig.getIdTypeSize...
                (lTargetWordSize);
            
            this.SingleThreadTiming = lSingleThreadTiming;
            
            this.ProfilingTimer = lProfilingTimer;
            
            this.GlobalRegistry = lGlobalRegistry;
            this.CodeDescriptor = codeDescriptor;
        end
        
        function targetWriteSectionBanner(~, writer, filename, isHeader, lProfilingTimer)
            banner = 'Code generated for instrumentation.';
            
            writer.writeLine('/*');
            writer.writeLine(' * File: %s', filename);
            writer.writeLine(' *');
            writer.writeLine(' * %s', banner);
            writer.writeLine(' *');
            
            if isempty(lProfilingTimer) && ~isHeader
                writer.writeLine(...
                    ' * This file contains stub implementations of the instrumentation utility');
                writer.writeLine(...
                    ' * functions. These stubs allow instrumented code to be compiled');
                writer.writeLine(...
                    ' * into an executable that does not support collection of execution');
                writer.writeLine(...
                    ' * instrumentation data.');
                writer.writeLine(' *');
            end
            
            writer.writeLine(' */');
            writer.newLine;
        end
        
        function targetWriteSectionLocalInclude(~, writer, filename)
            writer.writeLine('#include "%s"', filename);
            writer.newLine;
        end
        
        function targetWriteSectionExportedIncludes(this, writer)
            if ~isempty(this.ProfilingTimer)
                timerHeaderFile = this.ProfilingTimer.getTimerHeader;
                if ~isempty(timerHeaderFile)
                    writer.writeCellLines...
                        ({'/* Functions with a C call interface */';
                        '#ifdef __cplusplus';
                        'extern "C" {';
                        '#endif'});
                    writer.writeLine(['#include "' timerHeaderFile '"']);
                    writer.writeCellLines...
                        ({'#ifdef __cplusplus';
                        '}';
                        '#endif'});
                end
            end
            
            % Get basic type headers
            basicTypeIncludeLines = ...
                coder.profile.getBasicTypeIncludeLines(this.CodeDescriptor);

            % TopTester: test/toolbox/target/supportpackages/arduino/slworkflow/withECoders/tExecutionProfiling_NonHW.m
            for i=1:length(basicTypeIncludeLines)
                writer.writeLine(basicTypeIncludeLines{i});
            end
            writer.newLine;
        end
        
        function targetWriteSectionExportedFcnPrototypes(this, writer, collect)
            if ~isequal(length(collect), 0)
                writer.wComment('Upload code instrumentation data point');
                writer.writeLine('void %s(', collect);
                writer.incIndent;
                lCodeInstrSizeCDataType = ...
                    coder.profile.ExecTimeConfig.getCodeInstrNumElsCDataType...
                    (this.TargetWordSize);
                writer.writeLine('void* pData, %s numMemUnits, %s sectionId);',...
                                 lCodeInstrSizeCDataType, this.IdentifierCDataType);
                writer.decIndent;
                writer.newLine;
            end
        end
        
        function targetWriteSectionExportedAtomicFcn(this, writer, collect)
            if ~isempty(collect)
                writer.wComment('Atomic function to read timer and upload data point');
                writer.writeLine('void %s(%s sectionId);', collect, this.IdentifierCDataType);
                writer.newLine;
            end
        end
        
       function ret = targetWritePauseCall(~)
          % default implementation: no function called
          ret = '';
       end

       function ret = targetWriteTerminateCall(~)
          % default implementation: no function called
          ret = '';
       end

       function ret = targetWriteStepCall(~)
          % default implementation: no function called
          ret = '';
       end

       function ret = targetWriteInitCall(~)
          % default implementation: no function called
          ret = '';
       end
    end

    methods (Abstract, Access = public)
        targetWriteSectionFcns(this, writer, targetCollectDataFcnName, executed);
        targetWriteProbeExportedFcnPrototypes(this, writer, executed);
        targetWriteInit(this, executed);
    end
        
end

% LocalWords:  cplusplus extmode XCP
