"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.trackError = exports.reportError = exports.initializeErrorTracking = exports.configureErrorTracking = void 0;
var _services = require("@mirai/services");
var _helpers = require("../components/helpers");
var _Error$stack;
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const ERROR_TRACKING_FEATURE = 'errorTracking';
const MAX_REPORTS_PER_MESSAGE = 5;
const MAX_TRACKED_MESSAGES = 100;
const RATE_LIMIT_WINDOW_MS = 60000;
const resolveBase = url => {
  try {
    const _URL = new URL(url),
      origin = _URL.origin,
      pathname = _URL.pathname;
    return "".concat(origin).concat(pathname.replace(/[^/]*$/, ''));
  } catch (_unused) {
    return undefined;
  }
};
const CORE_BASE = resolveBase((_Error$stack = new Error().stack) === null || _Error$stack === void 0 || (_Error$stack = _Error$stack.match(/https?:\/\/[^\s)'"]+/)) === null || _Error$stack === void 0 ? void 0 : _Error$stack[0]) || resolveBase(process.env.SERVICE_STATIC && "".concat(process.env.SERVICE_STATIC, "/core/index.js"));
const reportedErrors = new WeakMap();
const messageCounts = new Map();
let errorContext = {};
let removeGlobalErrorListeners;
const isErrorTrackingEnabled = () => {
  const id = errorContext.chain || errorContext.hotel;
  return !!id && _services.ServiceFeatures.get(ERROR_TRACKING_FEATURE, id);
};
const isCoreUrl = url => !!CORE_BASE && typeof url === 'string' && url.startsWith(CORE_BASE);
const isStackFrame = line => /^\s*at\s/.test(line) || line.includes('@');
const stackHasCoreFrame = stack => typeof stack === 'string' && stack.split('\n').some(line => isStackFrame(line) && isCoreUrl((line.match(/https?:\/\/[^\s)'"]+/) || [])[0]));
const isCoreSource = function () {
  let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
    filename = _ref.filename,
    stack = _ref.stack;
  return filename ? isCoreUrl(filename) : stackHasCoreFrame(stack);
};
const isDuplicate = (error, now) => {
  if (error === null || typeof error !== 'object' && typeof error !== 'function') return false;
  const lastReported = reportedErrors.get(error);
  if (lastReported && now - lastReported <= RATE_LIMIT_WINDOW_MS) return true;
  reportedErrors.set(error, now);
  return false;
};
const isRateLimited = (message, now) => {
  const entry = messageCounts.get(message);
  if (entry && now - entry.since <= RATE_LIMIT_WINDOW_MS) {
    if (entry.count >= MAX_REPORTS_PER_MESSAGE) return true;
    entry.count += 1;
    return false;
  }
  if (!entry && messageCounts.size >= MAX_TRACKED_MESSAGES) messageCounts.delete(messageCounts.keys().next().value);
  messageCounts.set(message, {
    count: 1,
    since: now
  });
  return false;
};
const configureErrorTracking = function () {
  let _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
    hotel = _ref2.hotel,
    id = _ref2.id,
    session = _ref2.session,
    type = _ref2.type;
  errorContext = {
    chain: type === 'chain' ? id : undefined,
    hotel: hotel === null || hotel === void 0 ? void 0 : hotel.id,
    session
  };
};
exports.configureErrorTracking = configureErrorTracking;
const reportError = function (error) {
  let _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
    componentStack = _ref3.componentStack;
  const now = Date.now();
  if (isDuplicate(error, now)) return;
  const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || (typeof error === 'string' ? error : String(error !== null && error !== void 0 ? error : 'Unknown error'));
  if (isRateLimited(errorMessage, now)) return;
  const errorStack = [error === null || error === void 0 ? void 0 : error.stack, componentStack].filter(Boolean).join('\n') || undefined;
  trackError(errorMessage, errorStack);
};
exports.reportError = reportError;
const handleError = function () {
  let _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
    error = _ref4.error,
    message = _ref4.message,
    filename = _ref4.filename;
  if (!isCoreSource({
    filename,
    stack: error === null || error === void 0 ? void 0 : error.stack
  })) return;
  reportError(error !== null && error !== void 0 ? error : message);
};
const handleUnhandledRejection = function () {
  let _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
    reason = _ref5.reason;
  if (!isCoreSource({
    stack: reason === null || reason === void 0 ? void 0 : reason.stack
  })) return;
  reportError(reason);
};
const initializeErrorTracking = () => {
  if (removeGlobalErrorListeners) return removeGlobalErrorListeners;
  window.addEventListener('error', handleError);
  window.addEventListener('unhandledrejection', handleUnhandledRejection);
  removeGlobalErrorListeners = () => {
    window.removeEventListener('error', handleError);
    window.removeEventListener('unhandledrejection', handleUnhandledRejection);
    removeGlobalErrorListeners = undefined;
  };
  return removeGlobalErrorListeners;
};
exports.initializeErrorTracking = initializeErrorTracking;
const trackError = (errorMessage, errorStack) => {
  if (typeof errorMessage !== 'string' || errorMessage.trim() === '') return;
  if (window.IS_PLAYWRIGHT || window.location.host === 'monalisa.mirai.com' || !isErrorTrackingEnabled()) return;
  _services.ServiceAnna.track(_objectSpread(_objectSpread({}, errorContext), {}, {
    errorMessage,
    errorStack: errorStack ? typeof errorStack === 'object' ? JSON.stringify(errorStack) : String(errorStack) : undefined,
    eventName: _helpers.METRICS_EVENTS.ERROR_CORE
  }));
};
exports.trackError = trackError;
//# sourceMappingURL=trackError.js.map