"use strict";

// Honeybadger integration helper for jso-symbolicate.
//
// Honeybadger's `beforeNotify` callback receives the Notice before it ships.
// Use it to demangle errorClass, errorMessage, and the backtrace[] entries.
//
// Usage:
//
//   const Honeybadger = require("@honeybadger-io/js");
//   const { buildLookup } = require("jso-symbolicate");
//   const { createHoneybadgerBeforeNotify } = require("jso-symbolicate/honeybadger");
//
//   const lookup = buildLookup(
//       require("./report.json").Report.GlobalIdentifierMap,
//       require("./report.json").Report.MemberIdentifierMap
//   );
//
//   Honeybadger.configure({
//       apiKey: "...",
//       beforeNotify: createHoneybadgerBeforeNotify(lookup)
//   });

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

/**
 * Build a Honeybadger beforeNotify callback. Returns true so Honeybadger
 * continues sending the (demangled) notice. Returning false would drop the
 * notice — we never do that, since symbolication errors must not block
 * crash reporting.
 */
function createHoneybadgerBeforeNotify(lookup) {
    if (!lookup || typeof lookup !== "object") {
        return function () { return true; };
    }
    return function beforeNotify(notice) {
        try {
            if (!notice || typeof notice !== "object") return true;

            if (typeof notice.message === "string") notice.message = demangleStack(notice.message, lookup);
            if (typeof notice.name === "string") notice.name = demangleStack(notice.name, lookup);
            if (typeof notice.class === "string") notice.class = demangleStack(notice.class, lookup);

            // Both shapes have been observed in Honeybadger SDKs over time:
            // backtrace as an array of {method, file, number} entries, and
            // backtrace as a raw stack string.
            if (typeof notice.backtrace === "string") {
                notice.backtrace = demangleStack(notice.backtrace, lookup);
            } else if (Array.isArray(notice.backtrace)) {
                for (const frame of notice.backtrace) {
                    if (!frame) continue;
                    if (typeof frame.method === "string") frame.method = demangleStack(frame.method, lookup);
                    if (typeof frame.file === "string") frame.file = demangleStack(frame.file, lookup);
                    if (typeof frame.source === "string") frame.source = demangleStack(frame.source, lookup);
                }
            }
            if (notice.context && typeof notice.context === "object") {
                notice.context.jso_symbolicated = true;
            }
        } catch (e) {
            try {
                notice.context = notice.context || {};
                notice.context.jso_symbolicate_error = String(e && e.message || e);
            } catch (_) { /* ignore */ }
        }
        return true;
    };
}

module.exports = { createHoneybadgerBeforeNotify };
