import { defineIntegration, addBreadcrumb } from '@sentry/core';
import { logger } from '@sentry/node';
import { app, screen, powerMonitor, autoUpdater } from 'electron';
import { trackRendererProperties, getRendererProperties } from '../renderers.js';

const DEFAULT_OPTIONS = {
    // We exclude events starting with remote as they can be quite verbose
    app: (name) => !name.startsWith('remote-'),
    autoUpdater: () => true,
    webContents: (name) => ['dom-ready', 'context-menu', 'load-url', 'destroyed'].includes(name),
    browserWindow: (name) => [
        'closed',
        'close',
        'unresponsive',
        'responsive',
        'show',
        'blur',
        'focus',
        'hide',
        'maximize',
        'minimize',
        'restore',
        'enter-full-screen',
        'leave-full-screen',
    ].includes(name),
    screen: () => true,
    powerMonitor: () => true,
    captureWindowTitles: false,
};
/** Converts all user supplied options to function | false */
function normalizeOptions(options) {
    return Object.keys(options).reduce((obj, k) => {
        if (k === 'captureWindowTitles') {
            obj[k] = !!options[k];
        }
        else {
            const val = options[k];
            if (Array.isArray(val)) {
                obj[k] = (name) => val.includes(name);
            }
            else if (typeof val === 'function' || val === false) {
                obj[k] = val;
            }
        }
        return obj;
    }, {});
}
/**
 * Adds breadcrumbs for Electron events.
 */
const electronBreadcrumbsIntegration = defineIntegration((userOptions = {}) => {
    const options = {
        ...DEFAULT_OPTIONS,
        ...normalizeOptions(userOptions),
    };
    return {
        name: 'ElectronBreadcrumbs',
        setup(client) {
            const clientOptions = client.getOptions();
            const enableLogs = !!clientOptions?.enableLogs;
            function patchEventEmitter(emitter, category, shouldCapture, id) {
                const emit = emitter.emit.bind(emitter);
                emitter.emit = (event, ...args) => {
                    // eslint-disable-next-line typescript/prefer-optional-chain
                    if (shouldCapture && shouldCapture(event)) {
                        const breadcrumb = {
                            category: 'electron',
                            message: `${category}.${event}`,
                            timestamp: new Date().getTime() / 1000,
                            type: 'ui',
                        };
                        if (id) {
                            breadcrumb.data = { ...getRendererProperties(id) };
                            if (!options.captureWindowTitles && breadcrumb.data?.title) {
                                delete breadcrumb.data?.title;
                            }
                        }
                        addBreadcrumb(breadcrumb);
                        const attributes = {
                            'sentry.origin': 'auto.electron.events',
                        };
                        if (breadcrumb.data?.id) {
                            attributes.id = breadcrumb.data.id;
                        }
                        if (breadcrumb.data?.url) {
                            attributes.url = breadcrumb.data.url;
                        }
                        if (enableLogs) {
                            logger.info(logger.fmt `electron.${category}.${event}`, attributes);
                        }
                    }
                    return emit(event, ...args);
                };
            }
            trackRendererProperties();
            app.whenReady().then(() => {
                // We can't access these until app 'ready'
                if (options.screen) {
                    patchEventEmitter(screen, 'screen', options.screen);
                }
                if (options.powerMonitor) {
                    patchEventEmitter(powerMonitor, 'powerMonitor', options.powerMonitor);
                }
            }, () => {
                // ignore
            });
            if (options.app) {
                patchEventEmitter(app, 'app', options.app);
            }
            if (options.autoUpdater) {
                patchEventEmitter(autoUpdater, 'autoUpdater', options.autoUpdater);
            }
            if (options.browserWindow) {
                app.on('browser-window-created', (_, window) => {
                    const id = window.webContents.id;
                    const windowName = clientOptions?.getRendererName?.(window.webContents) || 'window';
                    patchEventEmitter(window, windowName, options.browserWindow, id);
                });
            }
            if (options.webContents) {
                app.on('web-contents-created', (_, contents) => {
                    const id = contents.id;
                    const webContentsName = clientOptions?.getRendererName?.(contents) || 'renderer';
                    patchEventEmitter(contents, webContentsName, options.webContents, id);
                });
            }
        },
    };
});

export { electronBreadcrumbsIntegration, normalizeOptions };
//# sourceMappingURL=electron-breadcrumbs.js.map
