function varargout = sfc( method, varargin)
% This is an entry point into Stateflow Code Generator
% for internal use only and not for general use.
% Help text is suppressed intentionally as
% this function is called by Stateflow internal code.
% Please refer to Stateflow API documentation for details
% on command line interface to code-generation.
%

%
%   Copyright 1995-2023 The MathWorks, Inc.
%
if(nargin<1)
    help(mfilename);
    return;
end

% nargin includes the "method" argument
nvarargin = nargin-1;

switch(lower(method))
    case 'coder_options'
        varargout = cell(1,max(1,nargout));
        varargout{:} = coder_options(varargin{:});
        return;
    case 'private'
        if(nvarargin<1)
            construct_coder_error([],'',1);
            return;
        end
        fcnName = varargin{1};
        inArgs = varargin(2:end);
        if(nargout>0)
            varargout = cell(1,nargout);
            [varargout{:}] = feval(fcnName,inArgs{:});
        else
            feval(fcnName,inArgs{:});
        end
        return;
    case 'revision'
        varargout{1} = '  ';
        return;
    case 'language'
        varargout{1} = 'ANSI-C';
        return;
    case {'clean_objects','clean','code','codeincremental','codenonincremental','filenameinfo','makeinfo','construct_chart_ir_for_rtw'}
        if(nvarargin<1)
            errorMsg = sprintf('Usage: sfc(methodName,targetId[,parentTargetId])');
            construct_coder_error([], errorMsg,1);
            return;
        end

        target = varargin{1};

        if(length(target)~=1 || ~sf('ishandle',target))
            errorMsg = sprintf('sfc invoked with invalid target id %d.',target);
            construct_coder_error([], errorMsg,1);
            return;
        end

        if(nvarargin>1)
            parentTarget = varargin{2};
        else
            parentTarget = target;
        end
        if(nvarargin>=3)
            mainMachineId = varargin{3};
        else
            mainMachineId = 0;
        end
        if(nvarargin>=4)
            currentChartId = varargin{4};
        else
            currentChartId = [];
        end
        if(nvarargin>=5)
            auxiliaryInfo = varargin{5};
        else
            auxiliaryInfo = [];
        end
        if(nvarargin>=6)
            hChart = varargin{6};
        else
            hChart = [];
        end

        if(length(parentTarget)~=1 || ~sf('ishandle',parentTarget))
            errorMsg = sprintf('sfc invoked with invalid parent target id %d.',parentTarget);
            construct_coder_error([], errorMsg,1);
        end
    otherwise
        construct_coder_error([],'',1);
        return;
end

sfprivate('coder_error_count_man','reset');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%% GLOBAL FLAGS AND ARRAYS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

global gTargetInfo gChartInfo gMachineInfo %#ok<GVMIS,NUSED>

%%%%%%%BEGIN: MINIMAL STUFF THAT NEEDS TO BE DONE%%%%%%%

gMachineInfo.target = target;
gMachineInfo.parentTarget = parentTarget;

gMachineInfo.mainMachineId = mainMachineId;
gMachineInfo.machineId = sf('get',gMachineInfo.target,'target.machine');
if(isempty(gMachineInfo.mainMachineId) || gMachineInfo.mainMachineId==0)
    gMachineInfo.mainMachineId = gMachineInfo.machineId;
end

gMachineInfo.charts = sfprivate('get_instantiated_charts_in_machine',gMachineInfo.machineId);
gMachineInfo.specializations = {};
singleChartCodegen = ~isempty(currentChartId);
if singleChartCodegen
    % this is used for HDL,PLC and other custom targets
    % for specified chart(s) only non-incrementally.
    %gMachineInfo.charts = intersect(gMachineInfo.charts, currentChartId);
    gMachineInfo.charts = currentChartId;
    if ~isempty(hChart)
        spec = sf('SFunctionSpecialization', currentChartId, hChart);
        gMachineInfo.specializations = {{spec}};
    end
end
chartFileNumbers = sf('get',gMachineInfo.charts,'chart.chartFileNumber');
[~,sortedIndices] = sort(chartFileNumbers);
gMachineInfo.charts = gMachineInfo.charts(sortedIndices);

gTargetInfo.target = target;
gTargetInfo.parentTarget = parentTarget;

%%%%%%%END:  MINIMAL STUFF THAT NEEDS TO BE DONE%%%%%%%

% The reason for using on cleanup up front instead of doing an explicit
% cdr_cleanup_all_info at the  end is that some of these methods throw
% exceptions and we might get an early return from somewhere in the middle
% of these switch cases.
cleaner = onCleanup(@() cdr_cleanup_all_info);

switch(method)
    case 'clean'
        [~, varargout{1}] = cdr_init_all_info;
        clean_code_gen_dir(varargout{1}.targetDirName');
    case 'clean_objects'
        [~, varargout{1}] = cdr_init_all_info;
        clean_code_gen_dir(varargout{1}.targetDirName,1);
    case {'code','codeIncremental','codeNonIncremental'}
        switch(method)
            case {'code','codeIncremental'}
                codingRebuildAll=0;
            case {'codeNonIncremental'}
                codingRebuildAll=1;
        end
        [status, varargout{1}] = cdr_init_all_info;
        sf('set',gTargetInfo.target,'target.makeInfo',varargout{1});

        if singleChartCodegen
            codingRebuildAll = 1;
        end

        if ~status
            status = construct_context_for_machine;
        end
        if(~status)
            generate_code_for_charts_and_machine(varargout{1},codingRebuildAll);
        end
    case 'construct_chart_ir_for_rtw'
        compute_target_info();
        compute_machine_info();
        gTargetInfo.codingIRConstructionForRTW = true;
        if gTargetInfo.gencpp
            gTargetInfo.fileNameInfo = create_file_name_info();
        end
        status = construct_context_for_machine(auxiliaryInfo);
        if ~status
            construct_chart_ir_for_rtw(currentChartId, hChart);
        end
    case 'filenameinfo'
        [~, varargout{1}] = cdr_init_all_info;
    case 'makeinfo'
        [~, makeInfo.fileNameInfo] =  cdr_init_all_info;
        varargout{1} = makeInfo;
    otherwise
        construct_coder_error([],'',1);
end

return;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [status, fileNameInfo] = cdr_init_all_info

status = 0;
compute_target_info();
compute_machine_info();
fileNameInfo = create_file_name_info();

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cdr_cleanup_all_info
global gMachineInfo %#ok<GVMIS>
sf('set',gMachineInfo.machineId,'machine.activeTarget',0);
sf('set',gMachineInfo.machineId,'machine.activeParentTarget',0);
clear global gMachineInfo gTargetInfo gChartInfo


