/*! @azure/msal-common v16.10.0 2026-06-23 */
'use strict';
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Log message level.
 */
var LogLevel;
(function (LogLevel) {
    LogLevel[LogLevel["Error"] = 0] = "Error";
    LogLevel[LogLevel["Warning"] = 1] = "Warning";
    LogLevel[LogLevel["Info"] = 2] = "Info";
    LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
    LogLevel[LogLevel["Trace"] = 4] = "Trace";
})(LogLevel || (LogLevel = {}));
// Shared cache state for better minification - using Map's insertion order for LRU
const CACHE_CAPACITY = 50;
const MAX_LOGS_PER_CORRELATION = 500;
const correlationCache = new Map();
/**
 * Mark correlation ID as recently used by moving it to end of Map
 * @param correlationId
 * @param {CorrelationLogData} data
 */
function markAsRecentlyUsed(correlationId, data) {
    correlationCache.delete(correlationId);
    correlationCache.set(correlationId, data);
}
/**
 * Add log message to cache for specific correlation ID
 * @param correlationId
 * @param {LoggedMessage} loggedMessage
 */
function addLogToCache(correlationId, loggedMessage) {
    const currentTime = Date.now();
    let data = correlationCache.get(correlationId);
    if (data) {
        // Mark as recently used
        markAsRecentlyUsed(correlationId, data);
    }
    else {
        // Create new entry
        data = { logs: [], firstEventTime: currentTime };
        correlationCache.set(correlationId, data);
        // Remove LRU (first entry) if capacity exceeded
        if (correlationCache.size > CACHE_CAPACITY) {
            const firstKey = correlationCache.keys().next().value;
            if (firstKey !== undefined) {
                correlationCache.delete(firstKey);
            }
        }
    }
    // Add log to the data, maintaining max logs per correlation
    data.logs.push({
        ...loggedMessage,
        milliseconds: currentTime - data.firstEventTime,
    });
    if (data.logs.length > MAX_LOGS_PER_CORRELATION) {
        data.logs.shift(); // Remove oldest log
    }
}
/**
 * Get logs for correlation ID and flush them from cache
 * Attaches logs with empty correlation id to the requested correlation logs
 * @param correlationId
 */
function getAndFlushLogsFromCache(correlationId) {
    const res = [];
    for (const id of ["", correlationId]) {
        const data = correlationCache.get(id);
        res.push(...(data?.logs ?? []));
        correlationCache.delete(id); // Remove the correlation ID completely from cache
    }
    return res;
}
/**
 * Extracts the leading minification hash from a log message, if present.
 *
 * Minified messages are produced by the logger-minify rollup plugin and are
 * either a bare 6-character alphanumeric hash, or that hash followed by a space
 * and runtime variables appended for local (console) logging, e.g.
 * "abc123 user-1 popup". Only the leading hash is returned so that telemetry
 * never captures the appended variables. Returns null when the message is not
 * a minified message.
 */
function getMessageHash(str) {
    if (str.length < 6) {
        return null;
    }
    /*
     * If the message is longer than the hash, the hash must be delimited by a
     * space (the separator the plugin inserts before appended variables).
     */
    if (str.length > 6 && str[6] !== " ") {
        return null;
    }
    for (let i = 0; i < 6; i++) {
        const char = str[i];
        const isAlphaNumeric = (char >= "a" && char <= "z") ||
            (char >= "A" && char <= "Z") ||
            (char >= "0" && char <= "9");
        if (!isAlphaNumeric) {
            return null;
        }
    }
    return str.substring(0, 6);
}
/**
 * Class which facilitates logging of messages to a specific place.
 */
class Logger {
    constructor(loggerOptions, packageName, packageVersion) {
        // Current log level, defaults to info.
        this.level = LogLevel.Info;
        const defaultLoggerCallback = () => {
            return;
        };
        const setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
        this.localCallback =
            setLoggerOptions.loggerCallback || defaultLoggerCallback;
        this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
        this.level =
            typeof setLoggerOptions.logLevel === "number"
                ? setLoggerOptions.logLevel
                : LogLevel.Info;
        this.packageName = packageName || "";
        this.packageVersion = packageVersion || "";
    }
    static createDefaultLoggerOptions() {
        return {
            loggerCallback: () => {
                // allow users to not set loggerCallback
            },
            piiLoggingEnabled: false,
            logLevel: LogLevel.Info,
        };
    }
    /**
     * Create new Logger with existing configurations.
     */
    clone(packageName, packageVersion) {
        return new Logger({
            loggerCallback: this.localCallback,
            piiLoggingEnabled: this.piiLoggingEnabled,
            logLevel: this.level,
        }, packageName, packageVersion);
    }
    /**
     * Log message with required options.
     */
    logMessage(logMessage, options) {
        const correlationId = options.correlationId;
        const messageHash = getMessageHash(logMessage);
        if (messageHash) {
            const loggedMessage = {
                hash: messageHash,
                level: options.logLevel,
                containsPii: options.containsPii || false,
                milliseconds: 0, // Will be calculated in addLogToCache
            };
            addLogToCache(correlationId, loggedMessage);
        }
        if (options.logLevel > this.level ||
            (!this.piiLoggingEnabled && options.containsPii)) {
            return;
        }
        const timestamp = new Date().toUTCString();
        // Add correlationId to logs if set, correlationId provided on log messages take precedence
        const logHeader = `[${timestamp}] : [${correlationId}]`;
        const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${LogLevel[options.logLevel]} - ${logMessage}`;
        this.executeCallback(options.logLevel, log, options.containsPii || false);
    }
    /**
     * Execute callback with message.
     */
    executeCallback(level, message, containsPii) {
        if (this.localCallback) {
            this.localCallback(level, message, containsPii);
        }
    }
    /**
     * Logs error messages.
     */
    error(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Error,
            containsPii: false,
            correlationId: correlationId,
        });
    }
    /**
     * Logs error messages with PII.
     */
    errorPii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Error,
            containsPii: true,
            correlationId: correlationId,
        });
    }
    /**
     * Logs warning messages.
     */
    warning(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Warning,
            containsPii: false,
            correlationId: correlationId,
        });
    }
    /**
     * Logs warning messages with PII.
     */
    warningPii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Warning,
            containsPii: true,
            correlationId: correlationId,
        });
    }
    /**
     * Logs info messages.
     */
    info(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Info,
            containsPii: false,
            correlationId: correlationId,
        });
    }
    /**
     * Logs info messages with PII.
     */
    infoPii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Info,
            containsPii: true,
            correlationId: correlationId,
        });
    }
    /**
     * Logs verbose messages.
     */
    verbose(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Verbose,
            containsPii: false,
            correlationId: correlationId,
        });
    }
    /**
     * Logs verbose messages with PII.
     */
    verbosePii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Verbose,
            containsPii: true,
            correlationId: correlationId,
        });
    }
    /**
     * Logs trace messages.
     */
    trace(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Trace,
            containsPii: false,
            correlationId: correlationId,
        });
    }
    /**
     * Logs trace messages with PII.
     */
    tracePii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Trace,
            containsPii: true,
            correlationId: correlationId,
        });
    }
    /**
     * Returns whether PII Logging is enabled or not.
     */
    isPiiLoggingEnabled() {
        return this.piiLoggingEnabled || false;
    }
}

export { LogLevel, Logger, getAndFlushLogsFromCache };
//# sourceMappingURL=Logger.mjs.map
