"use strict";

// Datadog Browser RUM / Logs SDK integration helper for jso-symbolicate.
//
// Datadog's browser SDK supports a `beforeSend` hook that receives the event
// before it ships. Use it to demangle exception classes, stack-trace text,
// and message bodies in-place.
//
// Usage:
//
//   import { datadogRum } from "@datadog/browser-rum";
//   const { buildLookup } = require("jso-symbolicate");
//   const { createDatadogBeforeSend } = require("jso-symbolicate/datadog");
//
//   const lookup = buildLookup(
//       window.__JSO_REPORT__.Report.GlobalIdentifierMap,
//       window.__JSO_REPORT__.Report.MemberIdentifierMap
//   );
//
//   datadogRum.init({
//       applicationId: "...",
//       clientToken: "...",
//       beforeSend: createDatadogBeforeSend(lookup)
//   });
//
// Same pattern works for `datadogLogs.init({ beforeSend: ... })`.

const { demangleStack } = require("./index.js");

/**
 * Build a Datadog beforeSend callback. Returns true so Datadog continues
 * sending the (now-demangled) event. Returning false would drop the event,
 * which we explicitly never do — symbolication errors must never block
 * crash reporting.
 */
function createDatadogBeforeSend(lookup) {
    if (!lookup || typeof lookup !== "object") {
        return function () { return true; };
    }
    return function beforeSend(event, context) {
        try {
            if (!event || typeof event !== "object") return true;

            // RUM error events
            const err = event.error;
            if (err && typeof err === "object") {
                if (typeof err.message === "string") err.message = demangleStack(err.message, lookup);
                if (typeof err.type === "string") err.type = demangleStack(err.type, lookup);
                if (typeof err.stack === "string") err.stack = demangleStack(err.stack, lookup);
                if (typeof err.source === "string") err.source = demangleStack(err.source, lookup);
            }

            // RUM action/view names sometimes contain function names too.
            const action = event.action;
            if (action && typeof action.target === "object" && typeof action.target.name === "string") {
                action.target.name = demangleStack(action.target.name, lookup);
            }

            // Logs SDK shape — top-level `message` and `error.stack`.
            if (typeof event.message === "string") {
                event.message = demangleStack(event.message, lookup);
            }

            // Attribute the demangling source so dashboards can filter by it.
            event.context = event.context || {};
            event.context.jso_symbolicated = true;
        } catch (e) {
            // Never block the event over a transform error.
            try {
                event.context = event.context || {};
                event.context.jso_symbolicate_error = String(e && e.message || e);
            } catch (_) { /* ignore */ }
        }
        return true;
    };
}

module.exports = { createDatadogBeforeSend };
