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


"use strict";
var _a;
import dynamicProto from "@microsoft/dynamicproto-js";
import { dumpObj, isFunction, isUndefined } from "@nevware21/ts-utils";
import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
import { _DYN_DIAG_LOG, _DYN_LOGGER, _DYN_LOGGING_LEVEL_CONSOL4, _DYN_MESSAGE, _DYN_MESSAGE_ID, _DYN_PUSH, _DYN_REPLACE, _DYN_THROW_INTERNAL, _DYN_UNLOAD, _DYN_WARN_TO_CONSOLE } from "../__DynamicConstants";
import { getDebugExt } from "./DbgExtensionUtils";
import { getConsole, getJSON, hasJSON } from "./EnvUtils";
import { STR_EMPTY } from "./InternalConstants";
var STR_WARN_TO_CONSOLE = "warnToConsole";
/**
 * For user non actionable traces use AI Internal prefix.
 */
var AiNonUserActionablePrefix = "AI (Internal): ";
/**
 * Prefix of the traces in portal.
 */
var AiUserActionablePrefix = "AI: ";
/**
 *  Session storage key for the prefix for the key indicating message type already logged
 */
var AIInternalMessagePrefix = "AITR_";
var defaultValues = {
    loggingLevelConsole: 0,
    loggingLevelTelemetry: 1,
    maxMessageLimit: 25,
    enableDebug: false
};
var _logFuncs = (_a = {},
    _a[0 /* eLoggingSeverity.DISABLED */] = null,
    _a[1 /* eLoggingSeverity.CRITICAL */] = "errorToConsole",
    _a[2 /* eLoggingSeverity.WARNING */] = STR_WARN_TO_CONSOLE,
    _a[3 /* eLoggingSeverity.DEBUG */] = "debugToConsole",
    _a);
function _sanitizeDiagnosticText(text) {
    if (text) {
        return "\"" + text[_DYN_REPLACE /* @min:%2ereplace */](/\"/g, STR_EMPTY) + "\"";
    }
    return STR_EMPTY;
}
function _logToConsole(func, message) {
    var theConsole = getConsole();
    if (!!theConsole) {
        var logFunc = "log";
        if (theConsole[func]) {
            logFunc = func;
        }
        if (isFunction(theConsole[logFunc])) {
            theConsole[logFunc](message);
        }
    }
}
var _InternalLogMessage = /** @class */ (function () {
    function _InternalLogMessage(msgId, msg, isUserAct, properties) {
        if (isUserAct === void 0) { isUserAct = false; }
        var _self = this;
        _self[_DYN_MESSAGE_ID /* @min:%2emessageId */] = msgId;
        _self[_DYN_MESSAGE /* @min:%2emessage */] =
            (isUserAct ? AiUserActionablePrefix : AiNonUserActionablePrefix) +
                msgId;
        var strProps = STR_EMPTY;
        if (hasJSON()) {
            strProps = getJSON().stringify(properties);
        }
        var diagnosticText = (msg ? " message:" + _sanitizeDiagnosticText(msg) : STR_EMPTY) +
            (properties ? " props:" + _sanitizeDiagnosticText(strProps) : STR_EMPTY);
        _self[_DYN_MESSAGE /* @min:%2emessage */] += diagnosticText;
    }
    _InternalLogMessage.dataType = "MessageData";
    return _InternalLogMessage;
}());
export { _InternalLogMessage };
export function safeGetLogger(core, config) {
    return (core || {})[_DYN_LOGGER /* @min:%2elogger */] || new DiagnosticLogger(config);
}
var DiagnosticLogger = /** @class */ (function () {
    function DiagnosticLogger(config) {
        this.identifier = "DiagnosticLogger";
        /**
         * The internal logging queue
         */
        this.queue = [];
        /**
         * Count of internal messages sent
         */
        var _messageCount = 0;
        /**
         * Holds information about what message types were already logged to console or sent to server.
         */
        var _messageLogged = {};
        var _loggingLevelConsole;
        var _loggingLevelTelemetry;
        var _maxInternalMessageLimit;
        var _enableDebug;
        var _unloadHandler;
        dynamicProto(DiagnosticLogger, this, function (_self) {
            _unloadHandler = _setDefaultsFromConfig(config || {});
            _self.consoleLoggingLevel = function () { return _loggingLevelConsole; };
            /**
             * This method will throw exceptions in debug mode or attempt to log the error as a console warning.
             * @param severity - The severity of the log message
             * @param message  - The log message.
             */
            _self[_DYN_THROW_INTERNAL /* @min:%2ethrowInternal */] = function (severity, msgId, msg, properties, isUserAct) {
                if (isUserAct === void 0) { isUserAct = false; }
                var message = new _InternalLogMessage(msgId, msg, isUserAct, properties);
                if (_enableDebug) {
                    throw dumpObj(message);
                }
                else {
                    // Get the logging function and fallback to warnToConsole of for some reason errorToConsole doesn't exist
                    var logFunc = _logFuncs[severity] || STR_WARN_TO_CONSOLE;
                    if (!isUndefined(message[_DYN_MESSAGE /* @min:%2emessage */])) {
                        if (isUserAct) {
                            // check if this message type was already logged to console for this page view and if so, don't log it again
                            var messageKey = +message[_DYN_MESSAGE_ID /* @min:%2emessageId */];
                            if (!_messageLogged[messageKey] && _loggingLevelConsole >= severity) {
                                _self[logFunc](message[_DYN_MESSAGE /* @min:%2emessage */]);
                                _messageLogged[messageKey] = true;
                            }
                        }
                        else {
                            // Only log traces if the console Logging Level is >= the throwInternal severity level
                            if (_loggingLevelConsole >= severity) {
                                _self[logFunc](message[_DYN_MESSAGE /* @min:%2emessage */]);
                            }
                        }
                        _logInternalMessage(severity, message);
                    }
                    else {
                        _debugExtMsg("throw" + (severity === 1 /* eLoggingSeverity.CRITICAL */ ? "Critical" : "Warning"), message);
                    }
                }
            };
            _self.debugToConsole = function (message) {
                _logToConsole("debug", message);
                _debugExtMsg("warning", message);
            };
            _self[_DYN_WARN_TO_CONSOLE /* @min:%2ewarnToConsole */] = function (message) {
                _logToConsole("warn", message);
                _debugExtMsg("warning", message);
            };
            _self.errorToConsole = function (message) {
                _logToConsole("error", message);
                _debugExtMsg("error", message);
            };
            _self.resetInternalMessageCount = function () {
                _messageCount = 0;
                _messageLogged = {};
            };
            _self.logInternalMessage = _logInternalMessage;
            _self[_DYN_UNLOAD /* @min:%2eunload */] = function (isAsync) {
                _unloadHandler && _unloadHandler.rm();
                _unloadHandler = null;
            };
            function _logInternalMessage(severity, message) {
                if (_areInternalMessagesThrottled()) {
                    return;
                }
                // check if this message type was already logged for this session and if so, don't log it again
                var logMessage = true;
                var messageKey = AIInternalMessagePrefix + message[_DYN_MESSAGE_ID /* @min:%2emessageId */];
                // if the session storage is not available, limit to only one message type per page view
                if (_messageLogged[messageKey]) {
                    logMessage = false;
                }
                else {
                    _messageLogged[messageKey] = true;
                }
                if (logMessage) {
                    // Push the event in the internal queue
                    if (severity <= _loggingLevelTelemetry) {
                        _self.queue[_DYN_PUSH /* @min:%2epush */](message);
                        _messageCount++;
                        _debugExtMsg((severity === 1 /* eLoggingSeverity.CRITICAL */ ? "error" : "warn"), message);
                    }
                    // When throttle limit reached, send a special event
                    if (_messageCount === _maxInternalMessageLimit) {
                        var throttleLimitMessage = "Internal events throttle limit per PageView reached for this app.";
                        var throttleMessage = new _InternalLogMessage(23 /* _eInternalMessageId.MessageLimitPerPVExceeded */, throttleLimitMessage, false);
                        _self.queue[_DYN_PUSH /* @min:%2epush */](throttleMessage);
                        if (severity === 1 /* eLoggingSeverity.CRITICAL */) {
                            _self.errorToConsole(throttleLimitMessage);
                        }
                        else {
                            _self[_DYN_WARN_TO_CONSOLE /* @min:%2ewarnToConsole */](throttleLimitMessage);
                        }
                    }
                }
            }
            function _setDefaultsFromConfig(config) {
                // make sure the config is dynamic
                return onConfigChange(createDynamicConfig(config, defaultValues, _self).cfg, function (details) {
                    var config = details.cfg;
                    _loggingLevelConsole = config[_DYN_LOGGING_LEVEL_CONSOL4 /* @min:%2eloggingLevelConsole */];
                    _loggingLevelTelemetry = config.loggingLevelTelemetry;
                    _maxInternalMessageLimit = config.maxMessageLimit;
                    _enableDebug = config.enableDebug;
                });
            }
            function _areInternalMessagesThrottled() {
                return _messageCount >= _maxInternalMessageLimit;
            }
            function _debugExtMsg(name, data) {
                var dbgExt = getDebugExt(config || {});
                if (dbgExt && dbgExt[_DYN_DIAG_LOG /* @min:%2ediagLog */]) {
                    dbgExt[_DYN_DIAG_LOG /* @min:%2ediagLog */](name, data);
                }
            }
        });
    }
// Removed Stub for DiagnosticLogger.prototype.consoleLoggingLevel.
// Removed Stub for DiagnosticLogger.prototype.throwInternal.
// Removed Stub for DiagnosticLogger.prototype.debugToConsole.
// Removed Stub for DiagnosticLogger.prototype.warnToConsole.
// Removed Stub for DiagnosticLogger.prototype.errorToConsole.
// Removed Stub for DiagnosticLogger.prototype.resetInternalMessageCount.
// Removed Stub for DiagnosticLogger.prototype.logInternalMessage.
// Removed Stub for DiagnosticLogger.prototype.unload.
    // 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.
    DiagnosticLogger.__ieDyn=1;

    return DiagnosticLogger;
}());
export { DiagnosticLogger };
function _getLogger(logger) {
    return (logger || new DiagnosticLogger());
}
/**
 * This is a helper method which will call throwInternal on the passed logger, will throw exceptions in
 * debug mode or attempt to log the error as a console warning. This helper is provided mostly to better
 * support minification as logger.throwInternal() will not compress the publish "throwInternal" used throughout
 * the code.
 * @param logger - The Diagnostic Logger instance to use.
 * @param severity - The severity of the log message
 * @param message  - The log message.
 */
export function _throwInternal(logger, severity, msgId, msg, properties, isUserAct) {
    if (isUserAct === void 0) { isUserAct = false; }
    _getLogger(logger)[_DYN_THROW_INTERNAL /* @min:%2ethrowInternal */](severity, msgId, msg, properties, isUserAct);
}
/**
 * This is a helper method which will call warnToConsole on the passed logger with the provided message.
 * @param logger - The Diagnostic Logger instance to use.
 * @param message  - The log message.
 */
export function _warnToConsole(logger, message) {
    _getLogger(logger)[_DYN_WARN_TO_CONSOLE /* @min:%2ewarnToConsole */](message);
}
/**
 * Logs a message to the internal queue.
 * @param logger - The Diagnostic Logger instance to use.
 * @param severity  - The severity of the log message
 * @param message - The message to log.
 */
export function _logInternalMessage(logger, severity, message) {
    _getLogger(logger).logInternalMessage(severity, message);
}
//# sourceMappingURL=DiagnosticLogger.js.map