import { stackParserFromStackParserOptions, getIntegrationsToSetup, debug, addAutoIpAddressToSession } from '@sentry/core';
import { eventFiltersIntegration, functionToStringIntegration, linkedErrorsIntegration, consoleIntegration, nativeNodeFetchIntegration, onUnhandledRejectionIntegration, contextLinesIntegration, localVariablesIntegration, nodeContextIntegration, setNodeAsyncContextStrategy, getCurrentScope, NodeClient, initOpenTelemetry } from '@sentry/node';
import { session } from 'electron';
import { IPCMode } from '../common/ipc.js';
import { getDefaultEnvironment, getDefaultReleaseName, getSdkInfo } from './context.js';
import { additionalContextIntegration } from './integrations/additional-context.js';
import { childProcessIntegration } from './integrations/child-process.js';
import { electronBreadcrumbsIntegration } from './integrations/electron-breadcrumbs.js';
import { electronContextIntegration } from './integrations/electron-context.js';
import { gpuContextIntegration } from './integrations/gpu-context.js';
import { mainProcessSessionIntegration } from './integrations/main-process-session.js';
import { electronNetIntegration } from './integrations/net-breadcrumbs.js';
import { normalizePathsIntegration } from './integrations/normalize-paths.js';
import { onUncaughtExceptionIntegration } from './integrations/onuncaughtexception.js';
import { preloadInjectionIntegration } from './integrations/preload-injection.js';
import { rendererEventLoopBlockIntegration } from './integrations/renderer-anr.js';
import { rendererProfilingIntegration } from './integrations/renderer-profiling.js';
import { screenshotsIntegration } from './integrations/screenshots.js';
import { sentryMinidumpIntegration } from './integrations/sentry-minidump/index.js';
import { configureIPC } from './ipc.js';
import { getOsDeviceLogAttributes } from './log.js';
import { defaultStackParser } from './stack-parse.js';
import { makeElectronOfflineTransport } from './transports/electron-offline-net.js';
import { configureUtilityProcessIPC } from './utility-processes.js';

/** Get the default integrations for the main process SDK. */
function getDefaultIntegrations(options) {
    const integrations = [
        // Electron integrations
        sentryMinidumpIntegration(), // we want this to run first as it enables the native crash handler
        electronBreadcrumbsIntegration(),
        electronNetIntegration(),
        electronContextIntegration(),
        childProcessIntegration(),
        onUncaughtExceptionIntegration(),
        preloadInjectionIntegration(),
        additionalContextIntegration(),
        screenshotsIntegration(),
        gpuContextIntegration(),
        rendererEventLoopBlockIntegration(),
        // Main process sessions
        mainProcessSessionIntegration(),
        // Node integrations
        eventFiltersIntegration(),
        functionToStringIntegration(),
        linkedErrorsIntegration(),
        consoleIntegration(),
        nativeNodeFetchIntegration(),
        onUnhandledRejectionIntegration(),
        contextLinesIntegration(),
        localVariablesIntegration(),
        nodeContextIntegration({ cloudResource: false }),
        // We want paths to be normailzed after we've captured context
        normalizePathsIntegration(),
    ];
    if (options.attachScreenshot) {
        integrations.push(screenshotsIntegration());
    }
    if (options.enableRendererProfiling) {
        integrations.push(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: getSdkInfo(inferIpAddress) },
        ipcMode: IPCMode.Both,
        ipcNamespace: 'sentry-ipc',
        release: getDefaultReleaseName(),
        environment: getDefaultEnvironment(),
        defaultIntegrations: getDefaultIntegrations(userOptions),
        transport: makeElectronOfflineTransport(),
        transportOptions: {},
        getSessions: () => [session.defaultSession],
        ...userOptions,
        stackParser: stackParserFromStackParserOptions(userOptions.stackParser || defaultStackParser),
        includeServerName: false,
    };
    const options = {
        ...optionsWithDefaults,
        integrations: getIntegrationsToSetup(optionsWithDefaults),
    };
    if (options.debug) {
        debug.enable();
    }
    removeRedundantIntegrations(options);
    configureUtilityProcessIPC();
    setNodeAsyncContextStrategy();
    const scope = getCurrentScope();
    scope.update(options.initialScope);
    const client = new NodeClient(options);
    if (inferIpAddress) {
        client.on('beforeSendSession', addAutoIpAddressToSession);
    }
    client.on('beforeCaptureLog', (log) => {
        log.attributes = {
            ...log.attributes,
            'electron.process': 'browser',
            ...getOsDeviceLogAttributes(client),
        };
    });
    scope.setClient(client);
    client.init();
    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) {
        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);
        }
    }
}

export { getDefaultIntegrations, init };
//# sourceMappingURL=sdk.js.map
