/* eslint-disable no-console */
/* eslint-env browser */
/**
 * This is the web browser implementation of `debug()`.
 */
import humanize from 'ms';
import setup from './common.js';
const storage = localstorage();
/**
 * Colors.
 */
const colors = [
    '#0000CC',
    '#0000FF',
    '#0033CC',
    '#0033FF',
    '#0066CC',
    '#0066FF',
    '#0099CC',
    '#0099FF',
    '#00CC00',
    '#00CC33',
    '#00CC66',
    '#00CC99',
    '#00CCCC',
    '#00CCFF',
    '#3300CC',
    '#3300FF',
    '#3333CC',
    '#3333FF',
    '#3366CC',
    '#3366FF',
    '#3399CC',
    '#3399FF',
    '#33CC00',
    '#33CC33',
    '#33CC66',
    '#33CC99',
    '#33CCCC',
    '#33CCFF',
    '#6600CC',
    '#6600FF',
    '#6633CC',
    '#6633FF',
    '#66CC00',
    '#66CC33',
    '#9900CC',
    '#9900FF',
    '#9933CC',
    '#9933FF',
    '#99CC00',
    '#99CC33',
    '#CC0000',
    '#CC0033',
    '#CC0066',
    '#CC0099',
    '#CC00CC',
    '#CC00FF',
    '#CC3300',
    '#CC3333',
    '#CC3366',
    '#CC3399',
    '#CC33CC',
    '#CC33FF',
    '#CC6600',
    '#CC6633',
    '#CC9900',
    '#CC9933',
    '#CCCC00',
    '#CCCC33',
    '#FF0000',
    '#FF0033',
    '#FF0066',
    '#FF0099',
    '#FF00CC',
    '#FF00FF',
    '#FF3300',
    '#FF3333',
    '#FF3366',
    '#FF3399',
    '#FF33CC',
    '#FF33FF',
    '#FF6600',
    '#FF6633',
    '#FF9900',
    '#FF9933',
    '#FFCC00',
    '#FFCC33'
];
/**
 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
 * and the Firebug extension (any Firefox version) are known
 * to support "%c" CSS customizations.
 *
 * TODO: add a `localStorage` variable to explicitly enable/disable colors
 */
// eslint-disable-next-line complexity
function useColors() {
    // NB: In an Electron preload script, document will be defined but not fully
    // initialized. Since we know we're in Chrome, we'll just detect this case
    // explicitly
    // @ts-expect-error window.process.type and window.process.__nwjs are not in the types
    if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
        return true;
    }
    // Internet Explorer and Edge do not support colors.
    if (typeof navigator !== 'undefined' && (navigator.userAgent?.toLowerCase().match(/(edge|trident)\/(\d+)/) != null)) {
        return false;
    }
    // Is webkit? http://stackoverflow.com/a/16459606/376773
    // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
    // @ts-expect-error document.documentElement.style.WebkitAppearance is not in the types
    return (typeof document !== 'undefined' && document.documentElement?.style?.WebkitAppearance) ||
        // Is firebug? http://stackoverflow.com/a/398120/376773
        // @ts-expect-error window.console.firebug and window.console.exception are not in the types
        (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
        // Is firefox >= v31?
        // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
        (typeof navigator !== 'undefined' && (navigator.userAgent?.toLowerCase().match(/firefox\/(\d+)/) != null) && parseInt(RegExp.$1, 10) >= 31) ||
        // Double check webkit in userAgent just in case we are in a worker
        (typeof navigator !== 'undefined' && navigator.userAgent?.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
 * Colorize log arguments if enabled.
 */
function formatArgs(args) {
    args[0] = (this.useColors ? '%c' : '') +
        this.namespace +
        (this.useColors ? ' %c' : ' ') +
        args[0] +
        (this.useColors ? '%c ' : ' ') +
        '+' + humanize(this.diff);
    if (!this.useColors) {
        return;
    }
    const c = 'color: ' + this.color;
    args.splice(1, 0, c, 'color: inherit');
    // The final "%c" is somewhat tricky, because there could be other
    // arguments passed either before or after the %c, so we need to
    // figure out the correct index to insert the CSS into
    let index = 0;
    let lastC = 0;
    args[0].replace(/%[a-zA-Z%]/g, (match) => {
        if (match === '%%') {
            return;
        }
        index++;
        if (match === '%c') {
            // We only are interested in the *last* %c
            // (the user may have provided their own)
            lastC = index;
        }
    });
    args.splice(lastC, 0, c);
}
/**
 * Invokes `console.debug()` when available.
 * No-op when `console.debug` is not a "function".
 * If `console.debug` is not available, falls back
 * to `console.log`.
 */
const log = console.debug ?? console.log ?? (() => { });
/**
 * Save `namespaces`.
 *
 * @param {string} namespaces
 */
function save(namespaces) {
    try {
        if (namespaces) {
            storage?.setItem('debug', namespaces);
        }
        else {
            storage?.removeItem('debug');
        }
    }
    catch (error) {
        // Swallow
        // XXX (@Qix-) should we be logging these?
    }
}
/**
 * Load `namespaces`.
 *
 * @returns {string} returns the previously persisted debug modes
 */
function load() {
    let r;
    try {
        r = storage?.getItem('debug');
    }
    catch (error) {
        // Swallow
        // XXX (@Qix-) should we be logging these?
    }
    // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
    if (!r && typeof globalThis.process !== 'undefined' && 'env' in globalThis.process) {
        r = globalThis.process.env.DEBUG;
    }
    return r;
}
/**
 * Localstorage attempts to return the localstorage.
 *
 * This is necessary because safari throws
 * when a user disables cookies/localstorage
 * and you attempt to access it.
 */
function localstorage() {
    try {
        // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
        // The Browser also has localStorage in the global context.
        return localStorage;
    }
    catch (error) {
        // Swallow
        // XXX (@Qix-) should we be logging these?
    }
}
function setupFormatters(formatters) {
    /**
     * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
     */
    formatters.j = function (v) {
        try {
            return JSON.stringify(v);
        }
        catch (error) {
            return '[UnexpectedJSONParseError]: ' + error.message;
        }
    };
}
export default setup({ formatArgs, save, load, useColors, setupFormatters, colors, storage, log });
//# sourceMappingURL=browser.js.map