function hDI = getDownstreamIntegrationDriver(this)
%

%   Copyright 2022-2023 The MathWorks, Inc.

% Get DownstreamIntegrationDriver for the model. The
% DownstreamIntegrationDriver is created lazily (i.e. when it is first
% accessed). At that time we also load the top-level settings, which can
% take a little tiem

modelName = this.getModelName;
if isempty(modelName)
    % If there is no model for this configset (e.g. configset reference),
    % then return empty
    hDI = [];
    return;
end

if ~isempty(this.DownstreamIntegrationDriver) && ~strcmp(this.DownstreamIntegrationDriver.getModelName, modelName)
    % When the model name does not match between the hdlcc object and its
    % DownstreamIntegrationDriver, we need to clear the existing
    % DownstreamIntegrationDriver, as it pertains to the wrong model. For
    % example, this can happen when the configset is copied. This will copy
    % the hdlcc object with a reference to the DownstreamIntegrationDriver
    % from the old model, which is not correct, so we clear the existing
    % one and recreate a new one.
    this.setDownstreamIntegrationDriver([]);
end

hDI = this.DownstreamIntegrationDriver;
if isempty(hDI)
    activeHDLCC = gethdlcc(this.getModelName);
    if activeHDLCC.hasDownstreamIntegrationDriver
        % Check if active configset already has a
        % DownstreamIntegrationDriver. If so, then we operating on a
        % non-active configset. In this case, we reuse the same
        % DownstreamIntegrationDriver from the active configset for this
        % (non-active) configset, since there can only be one
        % DownstreamIntegrationDriver per model (g3066350).
        % 
        % Note that this is technically not in-line with the configset
        % infrastructure, which treats the configset as a separate entity
        % from the model. However, HDL Coder does not yet support multiple
        % configsets or configset reference. At the moment, all HDL Coder
        % properties are stored on the model, and not in the configset, So
        % changes to HDL Coder properties on any of the configsets attached
        % to the model (active or non-active) will affect all the
        % configsets. Hence this behavior with the
        % DownstreamIntegrationDriver is consistent with the rest of the
        % HDL Coder configset and acceptable for now. This should be
        % updated when support for multiple configsets/configset reference
        % is added.
        hDI = activeHDLCC.getDownstreamIntegrationDriver;
        this.setDownstreamIntegrationDriver(hDI);
    else
        % Create DownstreamIntegrationDriver if nonexistent. This will call
        % setDownstreamIntegrationDriver inside the constructor on the hdlcc
        % object
        hDI = downstream.DownstreamIntegrationDriver(modelName, false, false, '', downstream.queryflowmodesenum.NONE, LoadModelSettings=false, LoadSimulationToolList=false);
    end
end

% Load top-level settings into the DownstreamIntegrationDriver
if ~hDI.IsTopLevelSettingsLoaded
    try
        hDI.loadTopLevelSettings(this.CLI);
    catch
        % Swallow any loading errors
    end
    hDI.syncWithConfigSet(this.CLI);
end

end
