"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseEventsStore = void 0;
var tslib_1 = require("tslib");
var constants_1 = require("../constants");
var BaseEventsStore = /** @class */ (function () {
    function BaseEventsStore(args) {
        var _this = this;
        var _a, _b, _c;
        this.minInterval = constants_1.MIN_INTERVAL;
        this.maxInterval = constants_1.MAX_INTERVAL;
        this.maxPersistedEventsSize = constants_1.DEFAULT_MAX_PERSISTED_EVENTS_SIZE_BYTES;
        this._timeAtLastSplit = Date.now(); // Initialize this so we have a point of comparison when events are recorded
        /**
         * Determines whether to send the events list to the backend and start a new
         * empty events list, based on the size of the list as well as the last time sent
         * @param nextEventString
         * @returns boolean
         */
        this.shouldSplitEventsList = function (events, nextEventString) {
            var sizeOfNextEvent = _this.getStringSize(nextEventString);
            var sizeOfEventsList = _this.getEventsArraySize(events);
            // Check size constraint first (most likely to trigger)
            if (sizeOfEventsList + sizeOfNextEvent >= _this.maxPersistedEventsSize) {
                return true;
            }
            if (Date.now() - _this.timeAtLastSplit > _this.interval && events.length) {
                _this.interval = Math.min(_this.maxInterval, _this.interval + _this.minInterval);
                _this._timeAtLastSplit = Date.now();
                return true;
            }
            return false;
        };
        this.loggerProvider = args.loggerProvider;
        this.minInterval = (_a = args.minInterval) !== null && _a !== void 0 ? _a : this.minInterval;
        this.maxInterval = (_b = args.maxInterval) !== null && _b !== void 0 ? _b : this.maxInterval;
        this.maxPersistedEventsSize = (_c = args.maxPersistedEventsSize) !== null && _c !== void 0 ? _c : this.maxPersistedEventsSize;
        this.interval = this.minInterval;
    }
    Object.defineProperty(BaseEventsStore.prototype, "timeAtLastSplit", {
        get: function () {
            return this._timeAtLastSplit;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Returns the UTF-8 byte size of a string without buffer allocation, matching the
     * actual wire byte count for non-ASCII content (Base64 image data, emoji, etc.).
     */
    BaseEventsStore.prototype.getStringSize = function (str) {
        var bytes = 0;
        for (var i = 0; i < str.length; i++) {
            var code = str.charCodeAt(i);
            if (code <= 0x7f) {
                bytes++;
            }
            else if (code <= 0x7ff) {
                bytes += 2;
            }
            else if (code >= 0xd800 && code <= 0xdbff) {
                // High surrogate — check for a valid low surrogate before consuming the pair.
                var next = i + 1 < str.length ? str.charCodeAt(i + 1) : NaN;
                if (next >= 0xdc00 && next <= 0xdfff) {
                    // Valid surrogate pair → encodes a code point above U+FFFF (4 UTF-8 bytes).
                    bytes += 4;
                    i++;
                }
                else {
                    // Orphaned high surrogate — treated as a replacement character (3 UTF-8 bytes).
                    bytes += 3;
                }
            }
            else if (code >= 0xdc00 && code <= 0xdfff) {
                // Orphaned low surrogate — treated as a replacement character (3 UTF-8 bytes).
                bytes += 3;
            }
            else {
                // Other BMP character (U+0800–U+FFFF, excluding surrogates): 3 UTF-8 bytes.
                bytes += 3;
            }
        }
        return bytes;
    };
    /**
     * Calculates the total UTF-8 byte size of events array
     * Accounts for JSON serialization overhead when sent to backend
     */
    BaseEventsStore.prototype.getEventsArraySize = function (events) {
        var e_1, _a;
        var totalSize = 0;
        try {
            for (var events_1 = tslib_1.__values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
                var event_1 = events_1_1.value;
                totalSize += this.getStringSize(event_1);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        // Approximate overhead from the array portion of the JSON payload:
        // - Array brackets: [] = 2 bytes
        // - Commas between events: events.length - 1 bytes
        // - Double quotes wrapping each event string: events.length * 2 bytes
        // Note: does not include the outer { version, events } wrapper (~22 bytes) or
        // per-event JSON-escaping of " and \ characters; the 2 MB MAX_EVENT_LIST_SIZE cap
        // stays well under the server's 10 MB decompressed split threshold even with those.
        var overhead = 2 + Math.max(0, events.length - 1) + events.length * 2;
        return totalSize + overhead;
    };
    return BaseEventsStore;
}());
exports.BaseEventsStore = BaseEventsStore;
//# sourceMappingURL=base-events-store.js.map