const core = require('@sentry/core');
const node = require('@sentry/node');
const electron = require('electron');
const ipc = require('../common/ipc.js');
const context = require('./context.js');
const additionalContext = require('./integrations/additional-context.js');
const childProcess = require('./integrations/child-process.js');
const electronBreadcrumbs = require('./integrations/electron-breadcrumbs.js');
const electronContext = require('./integrations/electron-context.js');
const gpuContext = require('./integrations/gpu-context.js');
const mainProcessSession = require('./integrations/main-process-session.js');
const netBreadcrumbs = require('./integrations/net-breadcrumbs.js');
const normalizePaths = require('./integrations/normalize-paths.js');
const onuncaughtexception = require('./integrations/onuncaughtexception.js');
const preloadInjection = require('./integrations/preload-injection.js');
const rendererAnr = require('./integrations/renderer-anr.js');
const rendererProfiling = require('./integrations/renderer-profiling.js');
const screenshots = require('./integrations/screenshots.js');
const index = require('./integrations/sentry-minidump/index.js');
const ipc$1 = require('./ipc.js');
const log = require('./log.js');
const stackParse = require('./stack-parse.js');
const electronOfflineNet = require('./transports/electron-offline-net.js');
const utilityProcesses = require('./utility-processes.js');

/** Get the default integrations for the main process SDK. */
function getDefaultIntegrations(options) {
    const integrations = [
        // Electron integrations
        index.sentryMinidumpIntegration(), // we want this to run first as it enables the native crash handler
        electronBreadcrumbs.electronBreadcrumbsIntegration(),
        netBreadcrumbs.electronNetIntegration(),
        electronContext.electronContextIntegration(),
        childProcess.childProcessIntegration(),
        onuncaughtexception.onUncaughtExceptionIntegration(),
        preloadInjection.preloadInjectionIntegration(),
        additionalContext.additionalContextIntegration(),
        screenshots.screenshotsIntegration(),
        gpuContext.gpuContextIntegration(),
        rendererAnr.rendererEventLoopBlockIntegration(),
        // Main process sessions
        mainProcessSession.mainProcessSessionIntegration(),
        // Node integrations
        node.eventFiltersIntegration(),
        node.functionToStringIntegration(),
        node.linkedErrorsIntegration(),
        node.consoleIntegration(),
        node.nativeNodeFetchIntegration(),
        node.onUnhandledRejectionIntegration(),
        node.contextLinesIntegration(),
        node.localVariablesIntegration(),
        node.nodeContextIntegration({ cloudResource: false }),
        // We want paths to be normailzed after we've captured context
        normalizePaths.normalizePathsIntegration(),
    ];
    if (options.attachScreenshot) {
        integrations.push(screenshots.screenshotsIntegration());
    }
    if (options.enableRendererProfiling) {
        integrations.push(rendererProfiling.rendererProfilingIntegration());
    }
    return integrations;
}
function resolveUserInfo(options) {
    const base = options.dataCollection != null ? true : !!options.sendDefaultPii;
    const dc = options.dataCollection ?? {};
    return dc.userInfo ?? base;
}
/**
 * Initialize Sentry in the Electron main process
 */
function init(userOptions) {
    const [major = 0] = process.versions.electron.split('.').map(Number);
    if (major < 23) {
        throw new Error('Sentry Electron SDK requires Electron 23 or higher');
    }
    const inferIpAddress = resolveUserInfo(userOptions);
    const optionsWithDefaults = {
        _metadata: { sdk: context.getSdkInfo(inferIpAddress) },
        ipcMode: ipc.IPCMode.Both,
        ipcNamespace: 'sentry-ipc',
        release: context.getDefaultReleaseName(),
        environment: context.getDefaultEnvironment(),
        defaultIntegrations: getDefaultIntegrations(userOptions),
        transport: electronOfflineNet.makeElectronOfflineTransport(),
        transportOptions: {},
        getSessions: () => [electron.session.defaultSession],
        ...userOptions,
        stackParser: core.stackParserFromStackParserOptions(userOptions.stackParser || stackParse.defaultStackParser),
        includeServerName: false,
    };
    const options = {
        ...optionsWithDefaults,
        integrations: core.getIntegrationsToSetup(optionsWithDefaults),
    };
    if (options.debug) {
        core.debug.enable();
    }
    removeRedundantIntegrations(options);
    utilityProcesses.configureUtilityProcessIPC();
    node.setNodeAsyncContextStrategy();
    const scope = node.getCurrentScope();
    scope.update(options.initialScope);
    const client = new node.NodeClient(options);
    if (inferIpAddress) {
        client.on('beforeSendSession', core.addAutoIpAddressToSession);
    }
    client.on('beforeCaptureLog', (log$1) => {
        log$1.attributes = {
            ...log$1.attributes,
            'electron.process': 'browser',
            ...log.getOsDeviceLogAttributes(client),
        };
    });
    scope.setClient(client);
    client.init();
    ipc$1.configureIPC(client, options);
    // If users opt-out of this, they _have_ to set up OpenTelemetry themselves
    // There is no way to use this SDK without OpenTelemetry!
    if (!options.skipOpenTelemetrySetup) {
        node.initOpenTelemetry(client);
    }
}
/** A list of integrations which cause default integrations to be removed */
const INTEGRATION_OVERRIDES = [
    { userAdded: 'ElectronMinidump', toRemove: 'SentryMinidump' },
    { userAdded: 'BrowserWindowSession', toRemove: 'MainProcessSession' },
];
/** Sets the default integrations and ensures that multiple minidump or session integrations are not enabled */
function removeRedundantIntegrations(
// At this point we know that the integrations are an array
options) {
    for (const { userAdded, toRemove } of INTEGRATION_OVERRIDES) {
        if (options.integrations.some((i) => i.name === userAdded)) {
            options.integrations = options.integrations.filter((i) => i.name !== toRemove);
        }
    }
}

exports.getDefaultIntegrations = getDefaultIntegrations;
exports.init = init;
//# sourceMappingURL=sdk.js.map
