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


var _a;
import { __spreadArrayFn as __spreadArray } from "@microsoft/applicationinsights-shims";
import dynamicProto from "@microsoft/dynamicproto-js";
import { createPromise, createSyncAllSettledPromise, doAwaitResponse } from "@nevware21/ts-async";
import { arrAppend, arrForEach, arrIndexOf, createTimeout, deepExtend, hasDocument, isFunction, isNullOrUndefined, isPlainObject, isPromiseLike, objDeepFreeze, objDefine, objForEachKey, objFreeze, objHasOwn, scheduleTimeout, throwError } from "@nevware21/ts-utils";
import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
import { ActiveStatus } from "../JavaScriptSDK.Enums/InitActiveStatusEnum";
import { _DYN_ADD_NOTIFICATION_LIS1, _DYN_CANCEL, _DYN_CREATE_NEW, _DYN_ENABLED, _DYN_GET_NOTIFY_MGR, _DYN_GET_PLUGIN, _DYN_GET_PROCESS_TEL_CONT2, _DYN_IDENTIFIER, _DYN_INITIALIZE, _DYN_IS_INITIALIZED, _DYN_LENGTH, _DYN_LOGGER, _DYN_LOGGING_LEVEL_CONSOL4, _DYN_MESSAGE, _DYN_MESSAGE_ID, _DYN_NAME, _DYN_ON_COMPLETE, _DYN_PROCESS_NEXT, _DYN_PUSH, _DYN_REMOVE_NOTIFICATION_0, _DYN_SPLICE, _DYN_STOP_POLLING_INTERNA3, _DYN_TEARDOWN, _DYN_UNLOAD, _DYN_VALUE, _DYN_VERSION, _DYN_WATCH } from "../__DynamicConstants";
import { doUnloadAll, runTargetUnload } from "./AsyncUtils";
import { ChannelControllerPriority } from "./Constants";
import { createCookieMgr } from "./CookieMgr";
import { createUniqueNamespace } from "./DataCacheHelper";
import { getDebugListener } from "./DbgExtensionUtils";
import { DiagnosticLogger, _InternalLogMessage, _throwInternal, _warnToConsole } from "./DiagnosticLogger";
import { getSetValue, isNotNullOrUndefined, proxyFunctionAs, proxyFunctions, toISOString } from "./HelperFuncs";
import { STR_CHANNELS, STR_CORE, STR_CREATE_PERF_MGR, STR_DISABLED, STR_EMPTY, STR_EVENTS_DISCARDED, STR_EXTENSIONS, STR_EXTENSION_CONFIG, STR_GET_PERF_MGR, STR_PRIORITY, UNDEFINED_VALUE } from "./InternalConstants";
import { NotificationManager } from "./NotificationManager";
import { PerfManager, doPerf, 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";
import { createUnloadHookContainer } from "./UnloadHookContainer";
// import { IStatsBeat, IStatsBeatConfig, IStatsBeatState } from "../JavaScriptSDK.Interfaces/IStatsBeat";
// import { IStatsMgr } from "../JavaScriptSDK.Interfaces/IStatsMgr";
var strValidationError = "Plugins must provide initialize method";
var strNotificationManager = "_notificationManager";
var strSdkUnloadingError = "SDK is still unloading...";
var strSdkNotInitialized = "SDK is not initialized";
var maxInitQueueSize = 100;
var maxInitTimeout = 50000;
// const strPluginUnloadFailed = "Failed to unload plugin";
// /**
//  * Default StatsBeatMgr configuration
//  * @internal
//  */
// const defaultStatsCfg: IConfigDefaults<IStatsBeatConfig> = objDeepFreeze({
//     shrtInt: UNDEFINED_VALUE,
//     endCfg: cfgDfMerge([])
// });
// /**
//  * Default SDK initialization configuration
//  * @internal
//  */
// const defaultSdkConfig: IConfigDefaults<IInternalSdkConfiguration> = objDeepFreeze({
//     stats: { rdOnly: true, mrg: true, v: defaultStatsCfg }
// });
/**
 * The default settings for the config.
 * WE MUST include all defaults here to ensure that the config is created with all of the properties
 * defined as dynamic.
 */
var defaultConfig = objDeepFreeze((_a = {
        cookieCfg: {}
    },
    _a[STR_EXTENSIONS] = { rdOnly: true, ref: true, v: [] },
    _a[STR_CHANNELS] = { rdOnly: true, ref: true, v: [] },
    _a[STR_EXTENSION_CONFIG] = { ref: true, v: {} },
    _a[STR_CREATE_PERF_MGR] = UNDEFINED_VALUE,
    _a.loggingLevelConsole = 0 /* eLoggingSeverity.DISABLED */,
    _a.diagnosticLogInterval = UNDEFINED_VALUE,
    _a));
/**
 * Helper to create the default performance manager
 * @param core - The AppInsightsCore instance
 * @param notificationMgr - The notification manager
 */
function _createPerfManager(core, notificationMgr) {
    return new PerfManager(notificationMgr);
}
function _validateExtensions(logger, channelPriority, allExtensions) {
    // Concat all available extensions
    var coreExtensions = [];
    var channels = [];
    // 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 channels
        if (!extPriority || extPriority < channelPriority) {
            // Add to core extension that will be managed by AppInsightsCore
            coreExtensions[_DYN_PUSH /* @min:%2epush */](ext);
        }
        else {
            channels[_DYN_PUSH /* @min:%2epush */](ext);
        }
    });
    return {
        core: coreExtensions,
        channels: channels
    };
}
function _isPluginPresent(thePlugin, plugins) {
    var exists = false;
    arrForEach(plugins, function (plugin) {
        if (plugin === thePlugin) {
            exists = true;
            return -1;
        }
    });
    return exists;
}
function _deepMergeConfig(details, target, newValues, merge) {
    // Lets assign the new values to the existing config
    if (newValues) {
        objForEachKey(newValues, function (key, value) {
            if (merge) {
                if (isPlainObject(value) && isPlainObject(target[key])) {
                    // The target is an object and it has a value
                    _deepMergeConfig(details, target[key], value, merge);
                }
            }
            if (merge && isPlainObject(value) && isPlainObject(target[key])) {
                // The target is an object and it has a value
                _deepMergeConfig(details, target[key], value, merge);
            }
            else {
                // Just Assign (replace) and/or make the property dynamic
                details.set(target, key, value);
            }
        });
    }
}
function _findWatcher(listeners, newWatcher) {
    var theListener = null;
    var idx = -1;
    arrForEach(listeners, function (listener, lp) {
        if (listener.w === newWatcher) {
            theListener = listener;
            idx = lp;
            return -1;
        }
    });
    return { i: idx, l: theListener };
}
function _addDelayedCfgListener(listeners, newWatcher) {
    var theListener = _findWatcher(listeners, newWatcher).l;
    if (!theListener) {
        theListener = {
            w: newWatcher,
            rm: function () {
                var fnd = _findWatcher(listeners, newWatcher);
                if (fnd.i !== -1) {
                    listeners[_DYN_SPLICE /* @min:%2esplice */](fnd.i, 1);
                }
            }
        };
        listeners[_DYN_PUSH /* @min:%2epush */](theListener);
    }
    return theListener;
}
function _registerDelayedCfgListener(config, listeners, logger) {
    arrForEach(listeners, function (listener) {
        var unloadHdl = onConfigChange(config, listener.w, logger);
        delete listener.w; // Clear the listener reference so it will get garbage collected.
        // replace the remove function
        listener.rm = function () {
            unloadHdl.rm();
        };
    });
}
// Moved this outside of the closure to reduce the retained memory footprint
function _initDebugListener(configHandler, unloadContainer, notificationManager, debugListener) {
    // Will get recalled if any referenced config values are changed
    unloadContainer.add(configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
        var disableDbgExt = details.cfg.disableDbgExt;
        if (disableDbgExt === true && debugListener) {
            // Remove any previously loaded debug listener
            notificationManager[_DYN_REMOVE_NOTIFICATION_0 /* @min:%2eremoveNotificationListener */](debugListener);
            debugListener = null;
        }
        if (notificationManager && !debugListener && disableDbgExt !== true) {
            debugListener = getDebugListener(details.cfg);
            notificationManager[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */](debugListener);
        }
    }));
    return debugListener;
}
// Moved this outside of the closure to reduce the retained memory footprint
function _createUnloadHook(unloadHook) {
    return objDefine({
        rm: function () {
            unloadHook.rm();
        }
    }, "toJSON", { v: function () { return "aicore::onCfgChange<" + JSON.stringify(unloadHook) + ">"; } });
}
/**
 * @group Classes
 * @group Entrypoint
 */
var AppInsightsCore = /** @class */ (function () {
    function AppInsightsCore() {
        // NOTE!: DON'T set default values here, instead set them in the _initDefaults() function as it is also called during teardown()
        var _configHandler;
        var _isInitialized;
        var _logger;
        var _eventQueue;
        var _notificationManager;
        // let _statsBeat: IStatsBeat | null;
        // let _statsMgr: IStatsMgr | null;
        var _perfManager;
        var _cfgPerfManager;
        var _cookieManager;
        var _pluginChain;
        var _configExtensions;
        var _channelConfig;
        var _channels;
        var _isUnloading;
        var _telemetryInitializerPlugin;
        var _internalLogsEventName;
        var _evtNamespace;
        var _unloadHandlers;
        var _hookContainer;
        var _debugListener;
        var _traceCtx;
        var _instrumentationKey;
        var _cfgListeners;
        var _extensions;
        var _pluginVersionStringArr;
        var _pluginVersionString;
        var _activeStatus; // to indicate if ikey or endpoint url promised is resolved or not
        var _endpoint;
        var _initInMemoMaxSize; // max event count limit during wait for init promises to be resolved
        var _isStatusSet; // track if active status is set in case of init timeout and init promises setting the status twice
        var _initTimer;
        /**
         * Internal log poller
         */
        var _internalLogPoller;
        var _internalLogPollerListening;
        var _forceStopInternalLogPoller;
        dynamicProto(AppInsightsCore, this, function (_self) {
            // Set the default values (also called during teardown)
            _initDefaults();
            // Special internal method to allow the unit tests and DebugPlugin to hook embedded objects
            _self["_getDbgPlgTargets"] = function () {
                return [_extensions, _eventQueue];
            };
            _self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */] = function () { return _isInitialized; };
            // since version 3.3.0
            _self.activeStatus = function () { return _activeStatus; };
            // since version 3.3.0
            // internal
            _self._setPendingStatus = function () {
                _activeStatus = 3 /* eActiveStatus.PENDING */;
            };
            // 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 cannot be initialized more than once");
                }
                _configHandler = createDynamicConfig(config, defaultConfig, logger || _self[_DYN_LOGGER /* @min:%2elogger */], false);
                // Re-assigning the local config property so we don't have any references to the passed value and it can be garbage collected
                config = _configHandler.cfg;
                // This will be "re-run" if the referenced config properties are changed
                _addUnloadHook(_configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
                    var rootCfg = details.cfg;
                    _initInMemoMaxSize = rootCfg.initInMemoMaxSize || maxInitQueueSize;
                    _handleIKeyEndpointPromises(rootCfg);
                    // Mark the extensionConfig and all first level keys as referenced
                    // This is so that calls to getExtCfg() will always return the same object
                    // Even when a user may "re-assign" the plugin properties (or it's unloaded/reloaded)
                    var extCfg = details.ref(details.cfg, STR_EXTENSION_CONFIG);
                    objForEachKey(extCfg, function (key) {
                        details.ref(extCfg, key);
                    });
                }));
                _notificationManager = notificationManager;
                // Initialize the debug listener outside of the closure to reduce the retained memory footprint
                _debugListener = _initDebugListener(_configHandler, _hookContainer, _notificationManager && _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */](), _debugListener);
                _initPerfManager();
                _self[_DYN_LOGGER /* @min:%2elogger */] = logger;
                var cfgExtensions = config[STR_EXTENSIONS /* @min:%2eextensions */];
                // Extension validation
                _configExtensions = [];
                _configExtensions[_DYN_PUSH /* @min:%2epush */].apply(_configExtensions, __spreadArray(__spreadArray([], extensions, false), cfgExtensions, false));
                _channelConfig = config[STR_CHANNELS /* @min:%2echannels */];
                _initPluginChain(null);
                if (!_channels || _channels[_DYN_LENGTH /* @min:%2elength */] === 0) {
                    throwError("No " + STR_CHANNELS + " available");
                }
                if (_channelConfig && _channelConfig[_DYN_LENGTH /* @min:%2elength */] > 1) {
                    var teeController = _self[_DYN_GET_PLUGIN /* @min:%2egetPlugin */]("TeeChannelController");
                    if (!teeController || !teeController.plugin) {
                        _throwInternal(_logger, 1 /* eLoggingSeverity.CRITICAL */, 28 /* _eInternalMessageId.SenderNotInitialized */, "TeeChannel required");
                    }
                }
                _registerDelayedCfgListener(config, _cfgListeners, _logger);
                _cfgListeners = null;
                _isInitialized = true;
                if (_activeStatus === ActiveStatus.ACTIVE) {
                    _releaseQueues();
                }
            };
            _self.getChannels = function () {
                var controls = [];
                if (_channels) {
                    arrForEach(_channels, function (channel) {
                        controls[_DYN_PUSH /* @min:%2epush */](channel);
                    });
                }
                return objFreeze(controls);
            };
            _self.track = function (telemetryItem) {
                doPerf(_self[STR_GET_PERF_MGR /* @min:%2egetPerfMgr */](), function () { return "AppInsightsCore:track"; }, function () {
                    if (telemetryItem === null) {
                        _notifyInvalidEvent(telemetryItem);
                        // throw error
                        throwError("Invalid telemetry item");
                    }
                    // do basic validation before sending it through the pipeline
                    if (!telemetryItem[_DYN_NAME /* @min:%2ename */] && isNullOrUndefined(telemetryItem[_DYN_NAME /* @min:%2ename */])) {
                        _notifyInvalidEvent(telemetryItem);
                        throwError("telemetry name required");
                    }
                    // setup default iKey if not passed in
                    telemetryItem.iKey = telemetryItem.iKey || _instrumentationKey;
                    // add default timestamp if not passed in
                    telemetryItem.time = telemetryItem.time || toISOString(new Date());
                    // Common Schema 4.0
                    telemetryItem.ver = telemetryItem.ver || "4.0";
                    if (!_isUnloading && _self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]() && _activeStatus === ActiveStatus.ACTIVE) {
                        // Process the telemetry plugin chain
                        _createTelCtx()[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](telemetryItem);
                    }
                    else if (_activeStatus !== ActiveStatus.INACTIVE) {
                        // Queue events until all extensions are initialized
                        if (_eventQueue[_DYN_LENGTH /* @min:%2elength */] <= _initInMemoMaxSize) {
                            // set limit, if full, stop adding new events
                            _eventQueue[_DYN_PUSH /* @min:%2epush */](telemetryItem);
                        }
                    }
                }, function () { return ({ item: telemetryItem }); }, !(telemetryItem.sync));
            };
            _self[_DYN_GET_PROCESS_TEL_CONT2 /* @min:%2egetProcessTelContext */] = _createTelCtx;
            _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */] = function () {
                if (!_notificationManager) {
                    _notificationManager = new NotificationManager(_configHandler.cfg);
                    // 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 listener - An INotificationListener object.
             */
            _self[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */] = function (listener) {
                _self.getNotifyMgr()[_DYN_ADD_NOTIFICATION_LIS1 /* @min:%2eaddNotificationListener */](listener);
            };
            /**
             * Removes all instances of the listener.
             * @param listener - INotificationListener to remove.
             */
            _self[_DYN_REMOVE_NOTIFICATION_0 /* @min:%2eremoveNotificationListener */] = function (listener) {
                if (_notificationManager) {
                    _notificationManager[_DYN_REMOVE_NOTIFICATION_0 /* @min:%2eremoveNotificationListener */](listener);
                }
            };
            _self.getCookieMgr = function () {
                if (!_cookieManager) {
                    _cookieManager = createCookieMgr(_configHandler.cfg, _self[_DYN_LOGGER /* @min:%2elogger */]);
                }
                return _cookieManager;
            };
            _self.setCookieMgr = function (cookieMgr) {
                if (_cookieManager !== cookieMgr) {
                    runTargetUnload(_cookieManager, false);
                    _cookieManager = cookieMgr;
                }
            };
            _self[STR_GET_PERF_MGR /* @min:%2egetPerfMgr */] = function () {
                return _perfManager || _cfgPerfManager || getGblPerfMgr();
            };
            _self.setPerfMgr = function (perfMgr) {
                _perfManager = perfMgr;
            };
            // _self.getStatsBeat = (statsBeatState: IStatsBeatState) => {
            //     // create a new statsbeat if not initialize yet or the endpoint is different
            //     // otherwise, return the existing one, or null
            //     if (statsBeatState) {
            //         if (_statsMgr && _statsMgr.enabled) {
            //             if (_statsBeat && _statsBeat.endpoint !== statsBeatState.endpoint) {
            //                 // Different endpoint, so unload the existing and create a new one
            //                 _statsBeat.enabled = false;
            //                 _statsBeat = null;
            //             }
            //             if (!_statsBeat) {
            //                 // Create a new statsbeat instance
            //                 _statsBeat = _statsMgr.newInst(statsBeatState);
            //             }
            //         } else if (_statsBeat) {
            //             // Disable and remove any previously created statsbeat instance
            //             _statsBeat.enabled = false;
            //             _statsBeat = null;
            //         }
            //         // Return the current statsbeat instance or null if not created
            //         return _statsBeat;
            //     }
            //     // Return null as no statsbeat state was provided
            //     return null;
            // };
            // _self.setStatsMgr = (statsMgr: IStatsMgr) => {
            //     if (_statsMgr && _statsMgr !== statsMgr) {
            //         // Disable any previously created statsbeat instance
            //         if (_statsBeat) {
            //             _statsBeat.enabled = false;
            //             _statsBeat = null;
            //         }
            //     }
            //     _statsMgr = statsMgr;
            // };
            _self.eventCnt = function () {
                return _eventQueue[_DYN_LENGTH /* @min:%2elength */];
            };
            _self.releaseQueue = function () {
                if (_isInitialized && _eventQueue[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    var eventQueue = _eventQueue;
                    _eventQueue = [];
                    if (_activeStatus === 2 /* eActiveStatus.ACTIVE */) {
                        arrForEach(eventQueue, function (event) {
                            event.iKey = event.iKey || _instrumentationKey;
                            _createTelCtx()[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](event);
                        });
                    }
                    else {
                        // new one for msg ikey
                        _throwInternal(_logger, 2 /* eLoggingSeverity.WARNING */, 20 /* _eInternalMessageId.FailedToSendQueuedTelemetry */, "core init status is not active");
                    }
                }
            };
            _self.pollInternalLogs = function (eventName) {
                _internalLogsEventName = eventName || null;
                _forceStopInternalLogPoller = false;
                _internalLogPoller && _internalLogPoller[_DYN_CANCEL /* @min:%2ecancel */]();
                return _startLogPoller(true);
            };
            function _handleIKeyEndpointPromises(theConfig) {
                // app Insights core only handle ikey and endpointurl, aisku will handle cs
                // But we want to reference these config values so that if any future changes are made
                // this will trigger the re-run of the watch function
                // and the ikey and endpointUrl will be set to the new values
                var ikey = theConfig.instrumentationKey;
                var endpointUrl = theConfig.endpointUrl; // do not need to validate endpoint url, if it is null, default one will be set by sender
                // Check if we are waiting for previous promises to be resolved, won't apply new changes
                if (_activeStatus !== 3 /* eActiveStatus.PENDING */) {
                    if (isNullOrUndefined(ikey)) {
                        _instrumentationKey = null;
                        // if new ikey is null, set status to be inactive, all new events will be saved in memory or dropped
                        _activeStatus = ActiveStatus.INACTIVE;
                        var msg = "Please provide instrumentation key";
                        if (!_isInitialized) {
                            // only throw error during initialization
                            throwError(msg);
                        }
                        else {
                            _throwInternal(_logger, 1 /* eLoggingSeverity.CRITICAL */, 100 /* _eInternalMessageId.InvalidInstrumentationKey */, msg);
                            _releaseQueues();
                        }
                        return;
                    }
                    var promises = [];
                    if (isPromiseLike(ikey)) {
                        promises[_DYN_PUSH /* @min:%2epush */](ikey);
                        _instrumentationKey = null; // reset current local ikey variable (otherwise it will always be the previous ikeys if timeout is called before promise cb)
                    }
                    else {
                        // string
                        _instrumentationKey = ikey;
                    }
                    if (isPromiseLike(endpointUrl)) {
                        promises[_DYN_PUSH /* @min:%2epush */](endpointUrl);
                        _endpoint = null; // reset current local endpoint variable (otherwise it will always be the previous urls if timeout is called before promise cb)
                    }
                    else {
                        // string or null
                        _endpoint = endpointUrl;
                    }
                    // at least have one promise
                    if (promises[_DYN_LENGTH /* @min:%2elength */]) {
                        _waitForInitPromises(theConfig, promises);
                    }
                    else {
                        // means no promises
                        _setStatus();
                    }
                }
            }
            function _waitForInitPromises(theConfig, promises) {
                // reset to false for new dynamic changes
                _isStatusSet = false;
                _activeStatus = 3 /* eActiveStatus.PENDING */;
                var initTimeout = isNotNullOrUndefined(theConfig.initTimeOut) ? theConfig.initTimeOut : maxInitTimeout; // theConfig.initTimeOut could be 0
                var allPromises = createSyncAllSettledPromise(promises);
                if (_initTimer) {
                    // Stop any previous timer
                    _initTimer[_DYN_CANCEL /* @min:%2ecancel */]();
                }
                _initTimer = scheduleTimeout(function () {
                    // set _isStatusSet to true
                    // set active status
                    // release queues
                    _initTimer = null;
                    if (!_isStatusSet) {
                        _setStatus();
                    }
                }, initTimeout);
                doAwaitResponse(allPromises, function (response) {
                    try {
                        if (_isStatusSet) {
                            // promises take too long to resolve, ignore them
                            // active status should be set by timeout already
                            return;
                        }
                        if (!response.rejected) {
                            var values = response[_DYN_VALUE /* @min:%2evalue */];
                            if (values && values[_DYN_LENGTH /* @min:%2elength */]) {
                                // ikey
                                var ikeyRes = values[0];
                                _instrumentationKey = ikeyRes && ikeyRes[_DYN_VALUE /* @min:%2evalue */];
                                // endpoint
                                if (values[_DYN_LENGTH /* @min:%2elength */] > 1) {
                                    var endpointRes = values[1];
                                    _endpoint = endpointRes && endpointRes[_DYN_VALUE /* @min:%2evalue */];
                                }
                            }
                            if (_instrumentationKey) {
                                // if ikey is null, no need to trigger extra dynamic changes for extensions
                                theConfig.instrumentationKey = _instrumentationKey; // set config.instrumentationKey for extensions to consume
                                theConfig.endpointUrl = _endpoint; // set config.endpointUrl for extensions to consume
                            }
                        }
                        // set _isStatusSet to true
                        // set active status
                        // release queues
                        _setStatus();
                    }
                    catch (e) {
                        if (!_isStatusSet) {
                            _setStatus();
                        }
                    }
                });
            }
            function _setStatus() {
                _isStatusSet = true;
                if (isNullOrUndefined(_instrumentationKey)) {
                    _activeStatus = ActiveStatus.INACTIVE;
                    _throwInternal(_logger, 1 /* eLoggingSeverity.CRITICAL */, 112 /* _eInternalMessageId.InitPromiseException */, "ikey can't be resolved from promises");
                }
                else {
                    _activeStatus = ActiveStatus.ACTIVE;
                }
                _releaseQueues();
            }
            function _releaseQueues() {
                if (_isInitialized) {
                    _self.releaseQueue();
                    _self.pollInternalLogs();
                }
            }
            function _startLogPoller(alwaysStart) {
                if ((!_internalLogPoller || !_internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */]) && !_forceStopInternalLogPoller) {
                    var shouldStart = alwaysStart || (_logger && _logger.queue[_DYN_LENGTH /* @min:%2elength */] > 0);
                    if (shouldStart) {
                        if (!_internalLogPollerListening) {
                            _internalLogPollerListening = true;
                            // listen for any configuration changes so that changes to the
                            // interval will cause the timer to be re-initialized
                            _addUnloadHook(_configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
                                var interval = details.cfg.diagnosticLogInterval;
                                if (!interval || !(interval > 0)) {
                                    interval = 10000;
                                }
                                var isRunning = false;
                                if (_internalLogPoller) {
                                    // It was already created so remember it's running and cancel
                                    isRunning = _internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */];
                                    _internalLogPoller[_DYN_CANCEL /* @min:%2ecancel */]();
                                }
                                // Create / reconfigure
                                _internalLogPoller = createTimeout(_flushInternalLogs, interval);
                                _internalLogPoller.unref();
                                // Restart if previously running
                                _internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */] = isRunning;
                            }));
                        }
                        _internalLogPoller[_DYN_ENABLED /* @min:%2eenabled */] = true;
                    }
                }
                return _internalLogPoller;
            }
            _self[_DYN_STOP_POLLING_INTERNA3 /* @min:%2estopPollingInternalLogs */] = function () {
                _forceStopInternalLogPoller = true;
                _internalLogPoller && _internalLogPoller[_DYN_CANCEL /* @min:%2ecancel */]();
                _flushInternalLogs();
            };
            // Add addTelemetryInitializer
            proxyFunctions(_self, function () { return _telemetryInitializerPlugin; }, ["addTelemetryInitializer"]);
            _self[_DYN_UNLOAD /* @min:%2eunload */] = function (isAsync, unloadComplete, cbTimeout) {
                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 = {
                    reason: 50 /* TelemetryUnloadReason.SdkUnload */,
                    isAsync: isAsync,
                    flushComplete: false
                };
                var result;
                if (isAsync && !unloadComplete) {
                    result = createPromise(function (resolve) {
                        // Set the callback to the promise resolve callback
                        unloadComplete = resolve;
                    });
                }
                var processUnloadCtx = createProcessTelemetryUnloadContext(_getPluginChain(), _self);
                processUnloadCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](function () {
                    // if (_statsBeat) {
                    //     // Disable any statsbeat instance
                    //     _statsBeat.enabled = false;
                    //     _statsBeat = null;
                    // }
                    _hookContainer.run(_self[_DYN_LOGGER /* @min:%2elogger */]);
                    // Run any "unload" functions for the _cookieManager, _notificationManager and _logger
                    doUnloadAll([_cookieManager, _notificationManager, _logger], isAsync, 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);
                }
                return result;
            };
            _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.updateCfg = function (newConfig, mergeExisting) {
                if (mergeExisting === void 0) { mergeExisting = true; }
                var updateState;
                if (_self[_DYN_IS_INITIALIZED /* @min:%2eisInitialized */]()) {
                    updateState = {
                        reason: 1 /* TelemetryUpdateReason.ConfigurationChanged */,
                        cfg: _configHandler.cfg,
                        oldCfg: deepExtend({}, _configHandler.cfg),
                        newConfig: deepExtend({}, newConfig),
                        merge: mergeExisting
                    };
                    newConfig = updateState.newConfig;
                    var cfg = _configHandler.cfg;
                    // replace the immutable (if initialized) values
                    // We don't currently allow updating the extensions and channels via the update config
                    // So overwriting any user provided values to reuse the existing values
                    newConfig[STR_EXTENSIONS /* @min:%2eextensions */] = cfg[STR_EXTENSIONS /* @min:%2eextensions */];
                    newConfig[STR_CHANNELS /* @min:%2echannels */] = cfg[STR_CHANNELS /* @min:%2echannels */];
                }
                // Explicitly blocking any previous config watchers so that they don't get called because
                // of this bulk update (Probably not necessary)
                _configHandler._block(function (details) {
                    // Lets assign the new values to the existing config either overwriting or re-assigning
                    var theConfig = details.cfg;
                    _deepMergeConfig(details, theConfig, newConfig, mergeExisting);
                    if (!mergeExisting) {
                        // Remove (unassign) the values "missing" from the newConfig and also not in the default config
                        objForEachKey(theConfig, function (key) {
                            if (!objHasOwn(newConfig, key)) {
                                // Set the value to undefined
                                details.set(theConfig, key, UNDEFINED_VALUE);
                            }
                        });
                    }
                    // Apply defaults to the new config
                    details.setDf(theConfig, defaultConfig);
                }, true);
                // Now execute all of the listeners (synchronously) so they update their values immediately
                _configHandler.notify();
                if (updateState) {
                    _doUpdate(updateState);
                }
            };
            _self.evtNamespace = function () {
                return _evtNamespace;
            };
            _self.flush = _flushChannels;
            _self.getTraceCtx = function (createNew) {
                if (!_traceCtx) {
                    _traceCtx = createDistributedTraceContext();
                }
                return _traceCtx;
            };
            _self.setTraceCtx = function (traceCtx) {
                _traceCtx = traceCtx || null;
            };
            _self.addUnloadHook = _addUnloadHook;
            // Create the addUnloadCb
            proxyFunctionAs(_self, "addUnloadCb", function () { return _unloadHandlers; }, "add");
            _self.onCfgChange = function (handler) {
                var unloadHook;
                if (!_isInitialized) {
                    unloadHook = _addDelayedCfgListener(_cfgListeners, handler);
                }
                else {
                    unloadHook = onConfigChange(_configHandler.cfg, handler, _self[_DYN_LOGGER /* @min:%2elogger */]);
                }
                return _createUnloadHook(unloadHook);
            };
            _self.getWParam = function () {
                return (hasDocument() || !!_configHandler.cfg.enableWParam) ? 0 : -1;
            };
            function _setPluginVersions() {
                var thePlugins = {};
                _pluginVersionStringArr = [];
                var _addPluginVersions = function (plugins) {
                    if (plugins) {
                        arrForEach(plugins, function (plugin) {
                            if (plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */] && plugin[_DYN_VERSION /* @min:%2eversion */] && !thePlugins[plugin.identifier]) {
                                var ver = plugin[_DYN_IDENTIFIER /* @min:%2eidentifier */] + "=" + plugin[_DYN_VERSION /* @min:%2eversion */];
                                _pluginVersionStringArr[_DYN_PUSH /* @min:%2epush */](ver);
                                thePlugins[plugin.identifier] = plugin;
                            }
                        });
                    }
                };
                _addPluginVersions(_channels);
                if (_channelConfig) {
                    arrForEach(_channelConfig, function (channels) {
                        _addPluginVersions(channels);
                    });
                }
                _addPluginVersions(_configExtensions);
            }
            function _initDefaults() {
                _isInitialized = false;
                // Use a default logger so initialization errors are not dropped on the floor with full logging
                _configHandler = createDynamicConfig({}, defaultConfig, _self[_DYN_LOGGER /* @min:%2elogger */]);
                // Set the logging level to critical so that any critical initialization failures are displayed on the console
                _configHandler.cfg[_DYN_LOGGING_LEVEL_CONSOL4 /* @min:%2eloggingLevelConsole */] = 1 /* eLoggingSeverity.CRITICAL */;
                // Define _self.config
                objDefine(_self, "config", {
                    g: function () { return _configHandler.cfg; },
                    s: function (newValue) {
                        _self.updateCfg(newValue, false);
                    }
                });
                objDefine(_self, "pluginVersionStringArr", {
                    g: function () {
                        if (!_pluginVersionStringArr) {
                            _setPluginVersions();
                        }
                        return _pluginVersionStringArr;
                    }
                });
                objDefine(_self, "pluginVersionString", {
                    g: function () {
                        if (!_pluginVersionString) {
                            if (!_pluginVersionStringArr) {
                                _setPluginVersions();
                            }
                            _pluginVersionString = _pluginVersionStringArr.join(";");
                        }
                        return _pluginVersionString || STR_EMPTY;
                    }
                });
                objDefine(_self, "logger", {
                    g: function () {
                        if (!_logger) {
                            _logger = new DiagnosticLogger(_configHandler.cfg);
                            _configHandler[_DYN_LOGGER /* @min:%2elogger */] = _logger;
                        }
                        return _logger;
                    },
                    s: function (newLogger) {
                        _configHandler[_DYN_LOGGER /* @min:%2elogger */] = newLogger;
                        if (_logger !== newLogger) {
                            runTargetUnload(_logger, false);
                            _logger = newLogger;
                        }
                    }
                });
                _self[_DYN_LOGGER /* @min:%2elogger */] = new DiagnosticLogger(_configHandler.cfg);
                _extensions = [];
                var cfgExtensions = _self.config[STR_EXTENSIONS /* @min:%2eextensions */] || [];
                cfgExtensions.splice(0, cfgExtensions[_DYN_LENGTH /* @min:%2elength */]);
                arrAppend(cfgExtensions, _extensions);
                _telemetryInitializerPlugin = new TelemetryInitializerPlugin();
                _eventQueue = [];
                runTargetUnload(_notificationManager, false);
                _notificationManager = null;
                _perfManager = null;
                // _statsBeat = null;
                _cfgPerfManager = null;
                runTargetUnload(_cookieManager, false);
                _cookieManager = null;
                _pluginChain = null;
                _configExtensions = [];
                _channelConfig = null;
                _channels = null;
                _isUnloading = false;
                _internalLogsEventName = null;
                _evtNamespace = createUniqueNamespace("AIBaseCore", true);
                _unloadHandlers = createUnloadHandlerContainer();
                _traceCtx = null;
                _instrumentationKey = null;
                _hookContainer = createUnloadHookContainer();
                _cfgListeners = [];
                _pluginVersionString = null;
                _pluginVersionStringArr = null;
                _forceStopInternalLogPoller = false;
                _internalLogPoller = null;
                _internalLogPollerListening = false;
                _activeStatus = 0 /* eActiveStatus.NONE */; // default is None
                _endpoint = null;
                _initInMemoMaxSize = null;
                _isStatusSet = false;
                _initTimer = null;
                // if (_statsBeat) {
                //     // Unload and disable any statsbeat instance
                //     _statsBeat.enabled = false;
                // }
                // _statsBeat = null;
            }
            function _createTelCtx() {
                var theCtx = createProcessTelemetryContext(_getPluginChain(), _configHandler.cfg, _self);
                theCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](_startLogPoller);
                return theCtx;
            }
            // Initialize or Re-initialize the plugins
            function _initPluginChain(updateState) {
                // Extension validation
                var theExtensions = _validateExtensions(_self[_DYN_LOGGER /* @min:%2elogger */], ChannelControllerPriority, _configExtensions);
                _pluginChain = null;
                _pluginVersionString = null;
                _pluginVersionStringArr = null;
                // Get the primary channel queue and include as part of the normal extensions
                _channels = (_channelConfig || [])[0] || [];
                // Add any channels provided in the extensions and sort them
                _channels = sortPlugins(arrAppend(_channels, theExtensions[STR_CHANNELS /* @min:%2echannels */]));
                // Create an array of all extensions, including the _channels
                var allExtensions = arrAppend(sortPlugins(theExtensions[STR_CORE /* @min:%2ecore */]), _channels);
                // Required to allow plugins to call core.getPlugin() during their own initialization
                _extensions = objFreeze(allExtensions);
                // This has a side effect of adding the extensions passed during initialization
                // into the config.extensions, so you can see all of the extensions loaded.
                // This will also get updated by the addPlugin() and remove plugin code.
                var cfgExtensions = _self.config[STR_EXTENSIONS /* @min:%2eextensions */] || [];
                cfgExtensions.splice(0, cfgExtensions[_DYN_LENGTH /* @min:%2elength */]);
                arrAppend(cfgExtensions, _extensions);
                var rootCtx = _createTelCtx();
                // Initializing the channels first
                if (_channels && _channels[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    initializePlugins(rootCtx[_DYN_CREATE_NEW /* @min:%2ecreateNew */](_channels), allExtensions);
                }
                // Now initialize the normal extensions (explicitly not including the _channels as this can cause duplicate initialization)
                initializePlugins(rootCtx, allExtensions);
                if (updateState) {
                    _doUpdate(updateState);
                }
            }
            function _getPlugin(pluginIdentifier) {
                var theExt = null;
                var thePlugin = null;
                var channelHosts = [];
                arrForEach(_extensions, function (ext) {
                    if (ext[_DYN_IDENTIFIER /* @min:%2eidentifier */] === pluginIdentifier && ext !== _telemetryInitializerPlugin) {
                        thePlugin = ext;
                        return -1;
                    }
                    if (ext.getChannel) {
                        channelHosts[_DYN_PUSH /* @min:%2epush */](ext);
                    }
                });
                if (!thePlugin && channelHosts[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    arrForEach(channelHosts, function (host) {
                        thePlugin = host.getChannel(pluginIdentifier);
                        if (!thePlugin) {
                            return -1;
                        }
                    });
                }
                if (thePlugin) {
                    theExt = {
                        plugin: thePlugin,
                        setEnabled: function (enabled) {
                            _getPluginState(thePlugin)[STR_DISABLED] = !enabled;
                        },
                        isEnabled: function () {
                            var pluginState = _getPluginState(thePlugin);
                            return !pluginState[_DYN_TEARDOWN /* @min:%2eteardown */] && !pluginState[STR_DISABLED];
                        },
                        remove: function (isAsync, removeCb) {
                            if (isAsync === void 0) { isAsync = true; }
                            var pluginsToRemove = [thePlugin];
                            var unloadState = {
                                reason: 1 /* TelemetryUnloadReason.PluginUnload */,
                                isAsync: isAsync
                            };
                            _removePlugins(pluginsToRemove, unloadState, function (removed) {
                                if (removed) {
                                    // Re-Initialize the plugin chain
                                    _initPluginChain({
                                        reason: 32 /* TelemetryUpdateReason.PluginRemoved */,
                                        removed: pluginsToRemove
                                    });
                                }
                                removeCb && removeCb(removed);
                            });
                        }
                    };
                }
                return theExt;
            }
            function _getPluginChain() {
                if (!_pluginChain) {
                    // copy the collection of extensions
                    var extensions = (_extensions || []).slice();
                    // During add / remove this may get called again, so don't read if already present
                    if (arrIndexOf(extensions, _telemetryInitializerPlugin) === -1) {
                        extensions[_DYN_PUSH /* @min:%2epush */](_telemetryInitializerPlugin);
                    }
                    _pluginChain = createTelemetryProxyChain(sortPlugins(extensions), _configHandler.cfg, _self);
                }
                return _pluginChain;
            }
            function _removePlugins(thePlugins, unloadState, removeComplete) {
                if (thePlugins && thePlugins[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    var unloadChain = createTelemetryProxyChain(thePlugins, _configHandler.cfg, _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;
                        _pluginVersionString = null;
                        _pluginVersionStringArr = null;
                        // 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);
                        _startLogPoller();
                    });
                    unloadCtx[_DYN_PROCESS_NEXT /* @min:%2eprocessNext */](unloadState);
                }
                else {
                    removeComplete(false);
                }
            }
            function _flushInternalLogs() {
                if (_logger && _logger.queue) {
                    var queue = _logger.queue.slice(0);
                    _logger.queue[_DYN_LENGTH /* @min:%2elength */] = 0;
                    arrForEach(queue, function (logMessage) {
                        var item = {
                            name: _internalLogsEventName ? _internalLogsEventName : "InternalMessageId: " + logMessage[_DYN_MESSAGE_ID /* @min:%2emessageId */],
                            iKey: _instrumentationKey,
                            time: toISOString(new Date()),
                            baseType: _InternalLogMessage.dataType,
                            baseData: { message: logMessage[_DYN_MESSAGE /* @min:%2emessage */] }
                        };
                        _self.track(item);
                    });
                }
            }
            function _flushChannels(isAsync, callBack, sendReason, cbTimeout) {
                // Setting waiting to one so that we don't call the callBack until we finish iterating
                var waiting = 1;
                var doneIterating = false;
                var cbTimer = null;
                cbTimeout = cbTimeout || 5000;
                function doCallback() {
                    waiting--;
                    if (doneIterating && waiting === 0) {
                        cbTimer && cbTimer[_DYN_CANCEL /* @min:%2ecancel */]();
                        cbTimer = null;
                        callBack && callBack(doneIterating);
                        callBack = null;
                    }
                }
                if (_channels && _channels[_DYN_LENGTH /* @min:%2elength */] > 0) {
                    var flushCtx = _createTelCtx()[_DYN_CREATE_NEW /* @min:%2ecreateNew */](_channels);
                    flushCtx.iterate(function (plugin) {
                        if (plugin.flush) {
                            waiting++;
                            var handled_1 = false;
                            // Not all channels will call this callback for every scenario
                            if (!plugin.flush(isAsync, function () {
                                handled_1 = true;
                                doCallback();
                            }, sendReason)) {
                                if (!handled_1) {
                                    // If any channel doesn't return true and it didn't call the callback, then we should assume that the callback
                                    // will never be called, so use a timeout to allow the channel(s) some time to "finish" before triggering any
                                    // followup function (such as unloading)
                                    if (isAsync && cbTimer == null) {
                                        cbTimer = scheduleTimeout(function () {
                                            cbTimer = null;
                                            doCallback();
                                        }, cbTimeout);
                                    }
                                    else {
                                        doCallback();
                                    }
                                }
                            }
                        }
                    });
                }
                doneIterating = true;
                doCallback();
                return true;
            }
            function _initPerfManager() {
                // Save the previous config based performance manager creator to avoid creating new perf manager instances if unchanged
                var prevCfgPerfMgr;
                // Will get recalled if any referenced config values are changed
                _addUnloadHook(_configHandler[_DYN_WATCH /* @min:%2ewatch */](function (details) {
                    var enablePerfMgr = details.cfg.enablePerfMgr;
                    if (enablePerfMgr) {
                        var createPerfMgr = details.cfg[STR_CREATE_PERF_MGR /* @min:%2ecreatePerfMgr */];
                        // for preCfgPerfMgr = createPerfMgr = null
                        // initial createPerfMgr function should be _createPerfManager
                        if ((prevCfgPerfMgr !== createPerfMgr) || !prevCfgPerfMgr) {
                            if (!createPerfMgr) {
                                createPerfMgr = _createPerfManager;
                            }
                            // Set the performance manager creation function if not defined
                            getSetValue(details.cfg, STR_CREATE_PERF_MGR, createPerfMgr);
                            prevCfgPerfMgr = createPerfMgr;
                            // Remove any existing config based performance manager
                            _cfgPerfManager = null;
                        }
                        // Only create the performance manager if it's not already created or manually set
                        if (!_perfManager && !_cfgPerfManager && isFunction(createPerfMgr)) {
                            // Create a new config based performance manager
                            _cfgPerfManager = createPerfMgr(_self, _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */]());
                        }
                    }
                    else {
                        // Remove any existing config based performance manager
                        _cfgPerfManager = null;
                        // Clear the previous cached value so it can be GC'd
                        prevCfgPerfMgr = null;
                    }
                }));
            }
            function _doUpdate(updateState) {
                var updateCtx = createProcessTelemetryUpdateContext(_getPluginChain(), _self);
                updateCtx[_DYN_ON_COMPLETE /* @min:%2eonComplete */](_startLogPoller);
                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);
                    _startLogPoller();
                }
                else {
                    throwError(message);
                }
            }
            function _notifyInvalidEvent(telemetryItem) {
                var manager = _self[_DYN_GET_NOTIFY_MGR /* @min:%2egetNotifyMgr */]();
                if (manager) {
                    manager[STR_EVENTS_DISCARDED /* @min:%2eeventsDiscarded */]([telemetryItem], 2 /* eEventsDiscardedReason.InvalidEvent */);
                }
            }
            function _addUnloadHook(hooks) {
                _hookContainer.add(hooks);
            }
        });
    }
// Removed Stub for AppInsightsCore.prototype.initialize.
// Removed Stub for AppInsightsCore.prototype.getChannels.
// Removed Stub for AppInsightsCore.prototype.track.
// Removed Stub for AppInsightsCore.prototype.getProcessTelContext.
// Removed Stub for AppInsightsCore.prototype.getNotifyMgr.
// Removed Stub for AppInsightsCore.prototype.addNotificationListener.
// Removed Stub for AppInsightsCore.prototype.removeNotificationListener.
// Removed Stub for AppInsightsCore.prototype.getCookieMgr.
// Removed Stub for AppInsightsCore.prototype.setCookieMgr.
// Removed Stub for AppInsightsCore.prototype.getPerfMgr.
    // public getStatsBeat(statsBeatState: IStatsBeatState): IStatsBeat {
    //     // @ DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
    //     return null;
    // }
    // public setStatsMgr(statsMgr?: IStatsMgr): void {
    //     // @ DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
    // }
// Removed Stub for AppInsightsCore.prototype.setPerfMgr.
// Removed Stub for AppInsightsCore.prototype.eventCnt.
// Removed Stub for AppInsightsCore.prototype.pollInternalLogs.
// Removed Stub for AppInsightsCore.prototype.stopPollingInternalLogs.
// Removed Stub for AppInsightsCore.prototype.addTelemetryInitializer.
// Removed Stub for AppInsightsCore.prototype.unload.
// Removed Stub for AppInsightsCore.prototype.getPlugin.
// Removed Stub for AppInsightsCore.prototype.addPlugin.
// Removed Stub for AppInsightsCore.prototype.updateCfg.
// Removed Stub for AppInsightsCore.prototype.evtNamespace.
// Removed Stub for AppInsightsCore.prototype.addUnloadCb.
// Removed Stub for AppInsightsCore.prototype.flush.
// Removed Stub for AppInsightsCore.prototype.getTraceCtx.
// Removed Stub for AppInsightsCore.prototype.setTraceCtx.
// Removed Stub for AppInsightsCore.prototype.addUnloadHook.
// Removed Stub for AppInsightsCore.prototype.onCfgChange.
// Removed Stub for AppInsightsCore.prototype.activeStatus.
// Removed Stub for AppInsightsCore.prototype._setPendingStatus.
// Removed Stub for AppInsightsCore.prototype.releaseQueue.
// Removed Stub for AppInsightsCore.prototype._updateHook.
    // This is a workaround for an IE 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.
    AppInsightsCore.__ieDyn=1;

    return AppInsightsCore;
}());
export { AppInsightsCore };
//# sourceMappingURL=AppInsightsCore.js.map