/*
 * Application Insights JavaScript SDK - Core, 2.8.15
 * Copyright (c) Microsoft and contributors. All rights reserved.
 */


"use strict";
import { __spreadArrayFn as __spreadArray } from "@microsoft/applicationinsights-shims";
import dynamicProto from "@microsoft/dynamicproto-js";
import { objCreateFn } from "@microsoft/applicationinsights-shims";
import { _DYN_ADD_NOTIFICATION_LIS1, _DYN_CONFIG, _DYN_FLUSH, _DYN_GET_NOTIFY_MGR, _DYN_GET_PLUGIN, _DYN_GET_PROCESS_TEL_CONT0, _DYN_IDENTIFIER, _DYN_INITIALIZE, _DYN_INSTRUMENTATION_KEY, _DYN_IS_ASYNC, _DYN_IS_INITIALIZED, _DYN_LENGTH, _DYN_LOGGER, _DYN_MESSAGE, _DYN_MESSAGE_ID, _DYN_NAME, _DYN_ON_COMPLETE, _DYN_PROCESS_NEXT, _DYN_PUSH, _DYN_REMOVE_NOTIFICATION_2, _DYN_SET_ENABLED, _DYN_SPLICE, _DYN_STOP_POLLING_INTERNA3, _DYN_TEARDOWN, _DYN_TIME, _DYN__EXTENSIONS } from "../__DynamicConstants";
import { ChannelControllerPriority, createChannelControllerPlugin, createChannelQueues } from "./ChannelController";
import { createCookieMgr } from "./CookieMgr";
import { createUniqueNamespace } from "./DataCacheHelper";
import { getDebugListener } from "./DbgExtensionUtils";
import { DiagnosticLogger, _InternalLogMessage, _throwInternal, _warnToConsole } from "./DiagnosticLogger";
import { arrForEach, arrIndexOf, getCfgValue, getSetValue, isFunction, isNullOrUndefined, objExtend, objFreeze, proxyFunctionAs, proxyFunctions, throwError, toISOString } from "./HelperFuncs";
import { STR_CHANNELS, STR_CORE, STR_CREATE_PERF_MGR, STR_DISABLED, STR_EVENTS_DISCARDED, STR_EVENTS_SEND_REQUEST, STR_EVENTS_SENT, STR_EXTENSIONS, STR_EXTENSION_CONFIG, STR_GET_PERF_MGR, STR_PRIORITY } from "./InternalConstants";
import { PerfManager, getGblPerfMgr } from "./PerfManager";
import { createProcessTelemetryContext, createProcessTelemetryUnloadContext, createProcessTelemetryUpdateContext, createTelemetryProxyChain } from "./ProcessTelemetryContext";
import { _getPluginState, createDistributedTraceContext, initializePlugins, sortPlugins } from "./TelemetryHelpers";
import { TelemetryInitializerPlugin } from "./TelemetryInitializerPlugin";
import { createUnloadHandlerContainer } from "./UnloadHandlerContainer";
var strValidationError = "Plugins must provide initialize method";
var strNotificationManager = "_notificationManager";
var strSdkUnloadingError = "SDK is still unloading...";
var strSdkNotInitialized = "SDK is not initialized";
// const strPluginUnloadFailed = "Failed to unload plugin";
var defaultInitConfig = {
    // Have the Diagnostic Logger default to log critical errors to the console
    loggingLevelConsole: 1 /* eLoggingSeverity.CRITICAL */
};
/**
 * Helper to create the default performance manager
 * @param core
 * @param notificationMgr
 */
function _createPerfManager(core, notificationMgr) {
    return new PerfManager(notificationMgr);
}
function _validateExtensions(logger, channelPriority, allExtensions) {
    var _a;
    // Concat all available extensions
    var coreExtensions = [];
    // Check if any two extensions have the same priority, then warn to console
    // And extract the local extensions from the
    var extPriorities = {};
    // Extension validation
    arrForEach(allExtensions, function (ext) {
        // Check for ext.initialize
        if (isNullOrUndefined(ext) || isNullOrUndefined(ext[_DYN_INITIALIZE /* @min:%2einitialize */])) {
            throwError(strValidationError);
        }
        var extPriority = ext[STR_PRIORITY /* @min:%2epriority */];
        var identifier = ext[_DYN_IDENTIFIER /* @min:%2eidentifier */];
        if (ext && extPriority) {
            if (!isNullOrUndefined(extPriorities[extPriority])) {
                _warnToConsole(logger, "Two extensions have same priority #" + extPriority + " - " + extPriorities[extPriority] + ", " + identifier);
            }
            else {
                // set a value
                extPriorities[extPriority] = identifier;
            }
        }
        // Split extensions to core and channelController
        if (!extPriority || extPriority < channelPriority) {
            // Add to core extension that will be managed by BaseCore
            coreExtensions[_DYN_PUSH /* @min:%2epush */](ext);
        }
    });
    return _a = {
            all: allExtensions
        },
        _a[STR_CORE /* @min:core */] = coreExtensions,
        _a;
}
function _isPluginPresent(thePlugin, plugins) {
    var exists = false;
    arrForEach(plugins, function (plugin) {
        if (plugin === thePlugin) {
            exists = true;
            return -1;
        }
    });
    return exists;
}
function _createDummyNotificationManager() {
    var _a;
    return objCreateFn((_a = {},
        _a[_DYN_ADD_NOTIFICATION_LIS1 /* @min:addNotificationListener */] = function (listener) { },
        _a[_DYN_REMOVE_NOTIFICATION_2 /* @min:removeNotificationListener */] = function (listener) { },
        _a[STR_EVENTS_SENT /* @min:eventsSent */] = function (events) { },
        _a[STR_EVENTS_DISCARDED /* @min:eventsDiscarded */] = function (events, reason) { },
        _a[STR_EVENTS_SEND_REQUEST /* @min:eventsSendRequest */] = function (sendReason, isAsync) { },
        _a));
}
var BaseCore = /** @class */ (function () {
    function BaseCore() {
        // NOTE!: DON'T set default values here, instead set them in the _initDefaults() function as it is also called during teardown()
        var _config;
        var _isInitialized;
        var _eventQueue;
        var _notificationManager;
        var _perfManager;
        var _cfgPerfManager;
        var _cookieManager;
        var _pluginChain;
        var _configExtensions;
        var _coreExtensions;
        var _channelControl;
        var _channelConfig;
        var _channelQueue;
        var _isUnloading;
        var _telemetryInitializerPlugin;
        var _internalLogsEventName;
        var _evtNamespace;
        var _unloadHandlers;
        var _debugListener;
        var _traceCtx;
        /**
         * Internal log poller
         */
        var _internalLogPoller = 0;
        var _forceStopInternalLogPoller = false;
        dynamicProto(BaseCore, this, function (_self) {
            // Set the default values (also called during teardown)
            _initDefaults();
            _self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */] = function () { return _isInitialized; };
            // Creating the self.initialize = ()
            _self[_DYN_INITIALIZE /* @min:%2einitialize */] = function (config, extensions, logger, notificationManager) {
                if (_isUnloading) {
                    throwError(strSdkUnloadingError);
                }
                // Make sure core is only initialized once
                if (_self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]()) {
                    throwError("Core should not be initialized more than once");
                }
                _config = config || {};
                _self[_DYN_CONFIG /* @min:%2econfig */] = _config;
                if (isNullOrUndefined(config[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */])) {
                    throwError("Please provide instrumentation key");
                }
                _notificationManager = notificationManager;
                // For backward compatibility only
                _self[strNotificationManager] = notificationManager;
                _initDebugListener();
                _initPerfManager();
                // add notification to the extensions in the config so other plugins can access it
                _initExtConfig();
                if (logger) {
                    _self[_DYN_LOGGER /* @min:%2elogger */] = logger;
                }
                var cfgExtensions = getSetValue(_config, STR_EXTENSIONS, []);
                // Extension validation
                _configExtensions = [];
                _configExtensions[_DYN_PUSH /* @min:%2epush */].apply(_configExtensions, __spreadArray(__spreadArray([], extensions, false), cfgExtensions, false));
                _channelConfig = getSetValue(_config, STR_CHANNELS, []);
                _initPluginChain(null);
                if (!_channelQueue || _channelQueue[_DYN_LENGTH /* @min:%2elength */] === 0) {
                    throwError("No " + STR_CHANNELS + " available");
                }
                _isInitialized = true;
                _self.releaseQueue();
            };
            _self.getTransmissionControls = function () {
                var controls = [];
                if (_channelQueue) {
                    arrForEach(_channelQueue, function (channels) {
                        controls[_DYN_PUSH /* @min:%2epush */](channels.queue);
                    });
                }
                return objFreeze(controls);
            };
            _self.track = function (telemetryItem) {
                // setup default iKey if not passed in
                telemetryItem.iKey = telemetryItem.iKey || _config[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */];
                // add default timestamp if not passed in
                telemetryItem[_DYN_TIME /* @min:%2etime */] = telemetryItem[_DYN_TIME /* @min:%2etime */] || toISOString(new Date());
                // Common Schema 4.0
                telemetryItem.ver = telemetryItem.ver || "4.0";
                if (!_isUnloading && _self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]()) {
                    // Process the telemetry plugin chain
                    _createTelCtx()[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](telemetryItem);
                }
                else {
                    // Queue events until all extensions are initialized
                    _eventQueue[_DYN_PUSH /* @min:%2epush */](telemetryItem);
                }
            };
            _self[_DYN_GET_PROCESS_TEL_CONT0 /* @min:%2egetProcessTelContext */] = _createTelCtx;
            _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */] = function () {
                if (!_notificationManager) {
                    // Create Dummy notification manager
                    _notificationManager = _createDummyNotificationManager();
                    // For backward compatibility only
                    _self[strNotificationManager] = _notificationManager;
                }
                return _notificationManager;
            };
            /**
             * Adds a notification listener. The SDK calls methods on the listener when an appropriate notification is raised.
             * The added plugins must raise notifications. If the plugins do not implement the notifications, then no methods will be
             * called.
             * @param {INotificationListener} listener - An INotificationListener object.
             */
            _self[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */] = function (listener) {
                if (_notificationManager) {
                    _notificationManager[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */](listener);
                }
            };
            /**
             * Removes all instances of the listener.
             * @param {INotificationListener} listener - INotificationListener to remove.
             */
            _self[_DYN_REMOVE_NOTIFICATION_2 /* @min:%2eremoveNotificationListener */] = function (listener) {
                if (_notificationManager) {
                    _notificationManager[_DYN_REMOVE_NOTIFICATION_2 /* @min:%2eremoveNotificationListener */](listener);
                }
            };
            _self.getCookieMgr = function () {
                if (!_cookieManager) {
                    _cookieManager = createCookieMgr(_config, _self[_DYN_LOGGER /* @min:%2elogger */]);
                }
                return _cookieManager;
            };
            _self.setCookieMgr = function (cookieMgr) {
                _cookieManager = cookieMgr;
            };
            _self[STR_GET_PERF_MGR /* @min:%2egetPerfMgr */] = function () {
                if (!_perfManager && !_cfgPerfManager) {
                    if (getCfgValue(_config.enablePerfMgr)) {
                        var createPerfMgr = getCfgValue(_config[STR_CREATE_PERF_MGR /* @min:%2ecreatePerfMgr */]);
                        if (isFunction(createPerfMgr)) {
                            _cfgPerfManager = createPerfMgr(_self, _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */]());
                        }
                    }
                }
                return _perfManager || _cfgPerfManager || getGblPerfMgr();
            };
            _self.setPerfMgr = function (perfMgr) {
                _perfManager = perfMgr;
            };
            _self.eventCnt = function () {
                return _eventQueue[_DYN_LENGTH /* @min:%2elength */];
            };
            _self.releaseQueue = function () {
                if (_isInitialized && _eventQueue[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    var eventQueue = _eventQueue;
                    _eventQueue = [];
                    arrForEach(eventQueue, function (event) {
                        _createTelCtx()[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](event);
                    });
                }
            };
            _self.pollInternalLogs = function (eventName) {
                _internalLogsEventName = eventName || null;
                _forceStopInternalLogPoller = false;
                if (_internalLogPoller) {
                    clearInterval(_internalLogPoller);
                    _internalLogPoller = null;
                }
                return _startInternalLogTimer(true);
            };
            function _startInternalLogTimer(alwaysStart) {
                if (!_internalLogPoller && !_forceStopInternalLogPoller) {
                    var shouldStart = alwaysStart || (_self[_DYN_LOGGER /* @min:%2elogger */] && _self[_DYN_LOGGER /* @min:%2elogger */].queue[_DYN_LENGTH /* @min:%2elength */] > 0);
                    if (shouldStart) {
                        var interval = getCfgValue(_config.diagnosticLogInterval);
                        if (!interval || !(interval > 0)) {
                            interval = 10000;
                        }
                        // Keeping as an interval timer for backward compatibility as it returns the result
                        _internalLogPoller = setInterval(function () {
                            clearInterval(_internalLogPoller);
                            _internalLogPoller = 0;
                            _flushInternalLogs();
                        }, interval);
                    }
                }
                return _internalLogPoller;
            }
            _self[_DYN_STOP_POLLING_INTERNA3 /* @min:%2estopPollingInternalLogs */] = function () {
                _forceStopInternalLogPoller = true;
                if (_internalLogPoller) {
                    clearInterval(_internalLogPoller);
                    _internalLogPoller = 0;
                    _flushInternalLogs();
                }
            };
            // Add addTelemetryInitializer
            proxyFunctions(_self, function () { return _telemetryInitializerPlugin; }, ["addTelemetryInitializer"]);
            _self.unload = function (isAsync, unloadComplete, cbTimeout) {
                var _a;
                if (isAsync === void 0) { isAsync = true; }
                if (!_isInitialized) {
                    // The SDK is not initialized
                    throwError(strSdkNotInitialized);
                }
                // Check if the SDK still unloading so throw
                if (_isUnloading) {
                    // The SDK is already unloading
                    throwError(strSdkUnloadingError);
                }
                var unloadState = (_a = {
                        reason: 50 /* TelemetryUnloadReason.SdkUnload */
                    },
                    _a[_DYN_IS_ASYNC /* @min:isAsync */] = isAsync,
                    _a.flushComplete = false,
                    _a);
                var processUnloadCtx = createProcessTelemetryUnloadContext(_getPluginChain(), _self);
                processUnloadCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](function () {
                    _initDefaults();
                    unloadComplete && unloadComplete(unloadState);
                }, _self);
                function _doUnload(flushComplete) {
                    unloadState.flushComplete = flushComplete;
                    _isUnloading = true;
                    // Run all of the unload handlers first (before unloading the plugins)
                    _unloadHandlers.run(processUnloadCtx, unloadState);
                    // Stop polling the internal logs
                    _self[_DYN_STOP_POLLING_INTERNA3 /* @min:%2estopPollingInternalLogs */]();
                    // Start unloading the components, from this point onwards the SDK should be considered to be in an unstable state
                    processUnloadCtx[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](unloadState);
                }
                _flushInternalLogs();
                if (!_flushChannels(isAsync, _doUnload, 6 /* SendRequestReason.SdkUnload */, cbTimeout)) {
                    _doUnload(false);
                }
            };
            _self[_DYN_GET_PLUGIN /* @min:%2egetPlugin */] = _getPlugin;
            _self.addPlugin = function (plugin, replaceExisting, isAsync, addCb) {
                if (!plugin) {
                    addCb && addCb(false);
                    _logOrThrowError(strValidationError);
                    return;
                }
                var existingPlugin = _getPlugin(plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */]);
                if (existingPlugin && !replaceExisting) {
                    addCb && addCb(false);
                    _logOrThrowError("Plugin [" + plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */] + "] is already loaded!");
                    return;
                }
                var updateState = {
                    reason: 16 /* TelemetryUpdateReason.PluginAdded */
                };
                function _addPlugin(removed) {
                    _configExtensions[_DYN_PUSH /* @min:%2epush */](plugin);
                    updateState.added = [plugin];
                    // Re-Initialize the plugin chain
                    _initPluginChain(updateState);
                    addCb && addCb(true);
                }
                if (existingPlugin) {
                    var removedPlugins_1 = [existingPlugin.plugin];
                    var unloadState = {
                        reason: 2 /* TelemetryUnloadReason.PluginReplace */,
                        isAsync: !!isAsync
                    };
                    _removePlugins(removedPlugins_1, unloadState, function (removed) {
                        if (!removed) {
                            // Previous plugin was successfully removed or was not installed
                            addCb && addCb(false);
                        }
                        else {
                            updateState.removed = removedPlugins_1;
                            updateState.reason |= 32 /* TelemetryUpdateReason.PluginRemoved */;
                            _addPlugin(true);
                        }
                    });
                }
                else {
                    _addPlugin(false);
                }
            };
            _self.evtNamespace = function () {
                return _evtNamespace;
            };
            _self[_DYN_FLUSH /* @min:%2eflush */] = _flushChannels;
            _self.getTraceCtx = function (createNew) {
                if (!_traceCtx) {
                    _traceCtx = createDistributedTraceContext();
                }
                return _traceCtx;
            };
            _self.setTraceCtx = function (traceCtx) {
                _traceCtx = traceCtx || null;
            };
            // Create the addUnloadCb
            proxyFunctionAs(_self, "addUnloadCb", function () { return _unloadHandlers; }, "add");
            function _initDefaults() {
                _isInitialized = false;
                // Use a default logger so initialization errors are not dropped on the floor with full logging
                _config = objExtend(true, {}, defaultInitConfig);
                _self[_DYN_CONFIG /* @min:%2econfig */] = _config;
                _self[_DYN_LOGGER /* @min:%2elogger */] = new DiagnosticLogger(_config);
                _self[_DYN__EXTENSIONS /* @min:%2e_extensions */] = [];
                _telemetryInitializerPlugin = new TelemetryInitializerPlugin();
                _eventQueue = [];
                _notificationManager = null;
                _perfManager = null;
                _cfgPerfManager = null;
                _cookieManager = null;
                _pluginChain = null;
                _coreExtensions = null;
                _configExtensions = [];
                _channelControl = null;
                _channelConfig = null;
                _channelQueue = null;
                _isUnloading = false;
                _internalLogsEventName = null;
                _evtNamespace = createUniqueNamespace("AIBaseCore", true);
                _unloadHandlers = createUnloadHandlerContainer();
                _traceCtx = null;
            }
            function _createTelCtx() {
                var theCtx = createProcessTelemetryContext(_getPluginChain(), _config, _self);
                theCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](_startInternalLogTimer);
                return theCtx;
            }
            // Initialize or Re-initialize the plugins
            function _initPluginChain(updateState) {
                // Extension validation
                var theExtensions = _validateExtensions(_self[_DYN_LOGGER /* @min:%2elogger */], ChannelControllerPriority, _configExtensions);
                _coreExtensions = theExtensions[STR_CORE /* @min:%2ecore */];
                _pluginChain = null;
                // Sort the complete set of extensions by priority
                var allExtensions = theExtensions.all;
                // Initialize the Channel Queues and the channel plugins first
                _channelQueue = objFreeze(createChannelQueues(_channelConfig, allExtensions, _self));
                if (_channelControl) {
                    // During add / remove of a plugin this may get called again, so don't re-add if already present
                    // But we also want the controller as the last, so remove if already present
                    // And reusing the existing instance, just in case an installed plugin has a reference and
                    // is using it.
                    var idx = arrIndexOf(allExtensions, _channelControl);
                    if (idx !== -1) {
                        allExtensions[_DYN_SPLICE /* @min:%2esplice */](idx, 1);
                    }
                    idx = arrIndexOf(_coreExtensions, _channelControl);
                    if (idx !== -1) {
                        _coreExtensions[_DYN_SPLICE /* @min:%2esplice */](idx, 1);
                    }
                    _channelControl._setQueue(_channelQueue);
                }
                else {
                    _channelControl = createChannelControllerPlugin(_channelQueue, _self);
                }
                // Add on "channelController" as the last "plugin"
                allExtensions[_DYN_PUSH /* @min:%2epush */](_channelControl);
                _coreExtensions[_DYN_PUSH /* @min:%2epush */](_channelControl);
                // Required to allow plugins to call core.getPlugin() during their own initialization
                _self[_DYN__EXTENSIONS /* @min:%2e_extensions */] = sortPlugins(allExtensions);
                // Initialize the controls
                _channelControl[_DYN_INITIALIZE /* @min:%2einitialize */](_config, _self, allExtensions);
                var initCtx = _createTelCtx();
                initializePlugins(initCtx, allExtensions);
                // Now reset the extensions to just those being managed by Basecore
                _self[_DYN__EXTENSIONS /* @min:%2e_extensions */] = objFreeze(sortPlugins(_coreExtensions || [])).slice();
                if (updateState) {
                    _doUpdate(updateState);
                }
            }
            function _getPlugin(pluginIdentifier) {
                var _a;
                var theExt = null;
                var thePlugin = null;
                arrForEach(_self[_DYN__EXTENSIONS /* @min:%2e_extensions */], function (ext) {
                    if (ext[_DYN_IDENTIFIER /* @min:%2eidentifier */] === pluginIdentifier && ext !== _channelControl && ext !== _telemetryInitializerPlugin) {
                        thePlugin = ext;
                        return -1;
                    }
                });
                if (!thePlugin && _channelControl) {
                    // Check the channel Controller
                    thePlugin = _channelControl.getChannel(pluginIdentifier);
                }
                if (thePlugin) {
                    theExt = (_a = {
                            plugin: thePlugin
                        },
                        _a[_DYN_SET_ENABLED /* @min:setEnabled */] = function (enabled) {
                            _getPluginState(thePlugin)[STR_DISABLED] = !enabled;
                        },
                        _a.isEnabled = function () {
                            var pluginState = _getPluginState(thePlugin);
                            return !pluginState[_DYN_TEARDOWN /* @min:%2eteardown */] && !pluginState[STR_DISABLED];
                        },
                        _a.remove = function (isAsync, removeCb) {
                            var _a;
                            if (isAsync === void 0) { isAsync = true; }
                            var pluginsToRemove = [thePlugin];
                            var unloadState = (_a = {
                                    reason: 1 /* TelemetryUnloadReason.PluginUnload */
                                },
                                _a[_DYN_IS_ASYNC /* @min:isAsync */] = isAsync,
                                _a);
                            _removePlugins(pluginsToRemove, unloadState, function (removed) {
                                if (removed) {
                                    // Re-Initialize the plugin chain
                                    _initPluginChain({
                                        reason: 32 /* TelemetryUpdateReason.PluginRemoved */,
                                        removed: pluginsToRemove
                                    });
                                }
                                removeCb && removeCb(removed);
                            });
                        },
                        _a);
                }
                return theExt;
            }
            function _getPluginChain() {
                if (!_pluginChain) {
                    // copy the collection of extensions
                    var extensions = (_coreExtensions || []).slice();
                    // During add / remove this may get called again, so don't readd if already present
                    if (arrIndexOf(extensions, _telemetryInitializerPlugin) === -1) {
                        extensions[_DYN_PUSH /* @min:%2epush */](_telemetryInitializerPlugin);
                    }
                    _pluginChain = createTelemetryProxyChain(sortPlugins(extensions), _config, _self);
                }
                return _pluginChain;
            }
            function _removePlugins(thePlugins, unloadState, removeComplete) {
                if (thePlugins && thePlugins[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    var unloadChain = createTelemetryProxyChain(thePlugins, _config, _self);
                    var unloadCtx = createProcessTelemetryUnloadContext(unloadChain, _self);
                    unloadCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](function () {
                        var removed = false;
                        // Remove the listed config extensions
                        var newConfigExtensions = [];
                        arrForEach(_configExtensions, function (plugin, idx) {
                            if (!_isPluginPresent(plugin, thePlugins)) {
                                newConfigExtensions[_DYN_PUSH /* @min:%2epush */](plugin);
                            }
                            else {
                                removed = true;
                            }
                        });
                        _configExtensions = newConfigExtensions;
                        // Re-Create the channel config
                        var newChannelConfig = [];
                        if (_channelConfig) {
                            arrForEach(_channelConfig, function (queue, idx) {
                                var newQueue = [];
                                arrForEach(queue, function (channel) {
                                    if (!_isPluginPresent(channel, thePlugins)) {
                                        newQueue[_DYN_PUSH /* @min:%2epush */](channel);
                                    }
                                    else {
                                        removed = true;
                                    }
                                });
                                newChannelConfig[_DYN_PUSH /* @min:%2epush */](newQueue);
                            });
                            _channelConfig = newChannelConfig;
                        }
                        removeComplete && removeComplete(removed);
                        _startInternalLogTimer();
                    });
                    unloadCtx[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](unloadState);
                }
                else {
                    removeComplete(false);
                }
            }
            function _flushInternalLogs() {
                if (_self[_DYN_LOGGER /* @min:%2elogger */] && _self[_DYN_LOGGER /* @min:%2elogger */].queue) {
                    var queue = _self[_DYN_LOGGER /* @min:%2elogger */].queue.slice(0);
                    _self[_DYN_LOGGER /* @min:%2elogger */].queue[_DYN_LENGTH /* @min:%2elength */] = 0;
                    arrForEach(queue, function (logMessage) {
                        var _a;
                        var item = (_a = {},
                            _a[_DYN_NAME /* @min:name */] = _internalLogsEventName ? _internalLogsEventName : "InternalMessageId: " + logMessage[_DYN_MESSAGE_ID /* @min:%2emessageId */],
                            _a.iKey = getCfgValue(_config[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */]),
                            _a.time = toISOString(new Date()),
                            _a.baseType = _InternalLogMessage.dataType,
                            _a.baseData = { message: logMessage[_DYN_MESSAGE /* @min:%2emessage */] },
                            _a);
                        _self.track(item);
                    });
                }
            }
            function _flushChannels(isAsync, callBack, sendReason, cbTimeout) {
                if (_channelControl) {
                    return _channelControl[_DYN_FLUSH /* @min:%2eflush */](isAsync, callBack, sendReason || 6 /* SendRequestReason.SdkUnload */, cbTimeout);
                }
                callBack && callBack(false);
                return true;
            }
            function _initDebugListener() {
                var disableDbgExt = getCfgValue(_config.disableDbgExt);
                if (disableDbgExt === true && _debugListener) {
                    // Remove any previously loaded debug listener
                    _notificationManager[_DYN_REMOVE_NOTIFICATION_2 /* @min:%2eremoveNotificationListener */](_debugListener);
                    _debugListener = null;
                }
                if (_notificationManager && !_debugListener && disableDbgExt !== true) {
                    _debugListener = getDebugListener(_config);
                    _notificationManager[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */](_debugListener);
                }
            }
            function _initPerfManager() {
                var enablePerfMgr = getCfgValue(_config.enablePerfMgr);
                if (!enablePerfMgr && _cfgPerfManager) {
                    // Remove any existing config based performance manager
                    _cfgPerfManager = null;
                }
                if (enablePerfMgr) {
                    // Set the performance manager creation function if not defined
                    getSetValue(_config, STR_CREATE_PERF_MGR, _createPerfManager);
                }
            }
            function _initExtConfig() {
                var extConfig = getSetValue(_config, STR_EXTENSION_CONFIG, {});
                extConfig.NotificationManager = _notificationManager;
            }
            function _doUpdate(updateState) {
                var updateCtx = createProcessTelemetryUpdateContext(_getPluginChain(), _self);
                updateCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](_startInternalLogTimer);
                if (!_self._updateHook || _self._updateHook(updateCtx, updateState) !== true) {
                    updateCtx[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](updateState);
                }
            }
            function _logOrThrowError(message) {
                var logger = _self[_DYN_LOGGER /* @min:%2elogger */];
                if (logger) {
                    // there should always be a logger
                    _throwInternal(logger, 2 /* eLoggingSeverity.WARNING */, 73 /* _eInternalMessageId.PluginException */, message);
                    _startInternalLogTimer();
                }
                else {
                    throwError(message);
                }
            }
        });
    }
// Removed Stub for BaseCore.prototype.initialize.
// Removed Stub for BaseCore.prototype.getTransmissionControls.
// Removed Stub for BaseCore.prototype.track.
// Removed Stub for BaseCore.prototype.getProcessTelContext.
// Removed Stub for BaseCore.prototype.getNotifyMgr.
// Removed Stub for BaseCore.prototype.addNotificationListener.
// Removed Stub for BaseCore.prototype.removeNotificationListener.
// Removed Stub for BaseCore.prototype.getCookieMgr.
// Removed Stub for BaseCore.prototype.setCookieMgr.
// Removed Stub for BaseCore.prototype.getPerfMgr.
// Removed Stub for BaseCore.prototype.setPerfMgr.
// Removed Stub for BaseCore.prototype.eventCnt.
// Removed Stub for BaseCore.prototype.pollInternalLogs.
// Removed Stub for BaseCore.prototype.stopPollingInternalLogs.
// Removed Stub for BaseCore.prototype.addTelemetryInitializer.
// Removed Stub for BaseCore.prototype.unload.
// Removed Stub for BaseCore.prototype.getPlugin.
// Removed Stub for BaseCore.prototype.addPlugin.
// Removed Stub for BaseCore.prototype.evtNamespace.
// Removed Stub for BaseCore.prototype.addUnloadCb.
// Removed Stub for BaseCore.prototype.flush.
// Removed Stub for BaseCore.prototype.getTraceCtx.
// Removed Stub for BaseCore.prototype.setTraceCtx.
// Removed Stub for BaseCore.prototype.releaseQueue.
// Removed Stub for BaseCore.prototype._updateHook.
    // This is a workaround for an IE8 bug when using dynamicProto() with classes that don't have any
    // non-dynamic functions or static properties/functions when using uglify-js to minify the resulting code.
    // this will be removed when ES3 support is dropped.
    BaseCore.__ieDyn=1;

    return BaseCore;
}());
export { BaseCore };
