import { __assign, __awaiter, __generator } from "tslib";
import { getGlobalScope, ServerZone } from '@amplitude/analytics-core';
import { getInputType } from '@amplitude/rrweb-snapshot';
import { DEFAULT_MASK_LEVEL } from './config/types';
import { KB_SIZE, MASK_TEXT_CLASS, SESSION_REPLAY_EU_URL, SESSION_REPLAY_SERVER_URL, SESSION_REPLAY_STAGING_URL, UNMASK_TEXT_CLASS, } from './constants';
/**
 * Light: Subset of inputs
 * Medium: All inputs
 * Conservative: All inputs and all texts
 */
var isMaskedForLevel = function (elementType, level, element) {
    switch (level) {
        case 'light': {
            if (elementType !== 'input') {
                return true;
            }
            var inputType = element ? getInputType(element) : '';
            /* istanbul ignore if */ // TODO(lew): For some reason it's impossible to test this.
            if (!inputType) {
                return false;
            }
            if (['password', 'hidden', 'email', 'tel'].includes(inputType)) {
                return true;
            }
            if (element.autocomplete.startsWith('cc-')) {
                return true;
            }
            return false;
        }
        case 'medium':
        case 'conservative':
            return true;
        default:
            return isMaskedForLevel(elementType, DEFAULT_MASK_LEVEL, element);
    }
};
/**
 * Checks if the given element set to be masked by rrweb
 *
 * Priority is:
 *  1. [In code] Element/class based masking/unmasking <> [Config based] Selector based masking/unmasking
 *  2. Use app defaults
 */
var isMasked = function (elementType, config, element) {
    var _a, _b, _c;
    if (config === void 0) { config = { defaultMaskLevel: DEFAULT_MASK_LEVEL }; }
    if (element) {
        // Element or parent is explicitly instrumented in code to mask
        if (element.closest('.' + MASK_TEXT_CLASS)) {
            return true;
        }
        // Config has override for mask
        var shouldMask = ((_a = config.maskSelector) !== null && _a !== void 0 ? _a : []).some(function (selector) { return element.closest(selector); });
        if (shouldMask) {
            return true;
        }
        // Code or config has override to unmask
        if (element.closest('.' + UNMASK_TEXT_CLASS)) {
            return false;
        }
        // Here we are probably sent an element, but we want to match if they have a
        // parent with an unmask selector.
        var shouldUnmask = ((_b = config.unmaskSelector) !== null && _b !== void 0 ? _b : []).some(function (selector) { return element.closest(selector); });
        if (shouldUnmask) {
            return false;
        }
    }
    return isMaskedForLevel(elementType, (_c = config.defaultMaskLevel) !== null && _c !== void 0 ? _c : DEFAULT_MASK_LEVEL, element);
};
export var maskFn = function (elementType, config) {
    return function (text, element) {
        return isMasked(elementType, config, element) ? text.replace(/[^\s]/g, '*') : text;
    };
};
export var generateHashCode = function (str) {
    var hash = 0;
    if (str.length === 0)
        return hash;
    for (var i = 0; i < str.length; i++) {
        var chr = str.charCodeAt(i);
        hash = (hash << 5) - hash + chr;
        hash |= 0;
    }
    return hash;
};
export var isSessionInSample = function (sessionId, sampleRate) {
    var hashNumber = generateHashCode(sessionId.toString());
    var absHash = Math.abs(hashNumber);
    var absHashMultiply = absHash * 31;
    var mod = absHashMultiply % 1000000;
    return mod / 1000000 < sampleRate;
};
export var getCurrentUrl = function () {
    var globalScope = getGlobalScope();
    return (globalScope === null || globalScope === void 0 ? void 0 : globalScope.location) ? globalScope.location.href : '';
};
export var generateSessionReplayId = function (sessionId, deviceId) {
    return "".concat(deviceId, "/").concat(sessionId);
};
export var getServerUrl = function (serverZone, trackServerUrl) {
    if (trackServerUrl) {
        return trackServerUrl;
    }
    if (serverZone === ServerZone.STAGING) {
        return SESSION_REPLAY_STAGING_URL;
    }
    if (serverZone === ServerZone.EU) {
        return SESSION_REPLAY_EU_URL;
    }
    return SESSION_REPLAY_SERVER_URL;
};
export var getStorageSize = function () { return __awaiter(void 0, void 0, void 0, function () {
    var globalScope, _a, usage, quota, usageDetails, totalStorageSize, percentOfQuota, e_1;
    return __generator(this, function (_b) {
        switch (_b.label) {
            case 0:
                _b.trys.push([0, 3, , 4]);
                globalScope = getGlobalScope();
                if (!globalScope) return [3 /*break*/, 2];
                return [4 /*yield*/, globalScope.navigator.storage.estimate()];
            case 1:
                _a = _b.sent(), usage = _a.usage, quota = _a.quota, usageDetails = _a.usageDetails;
                totalStorageSize = usage ? Math.round(usage / KB_SIZE) : 0;
                percentOfQuota = usage && quota ? Math.round((usage / quota + Number.EPSILON) * 1000) / 1000 : 0;
                return [2 /*return*/, { totalStorageSize: totalStorageSize, percentOfQuota: percentOfQuota, usageDetails: JSON.stringify(usageDetails) }];
            case 2: return [3 /*break*/, 4];
            case 3:
                e_1 = _b.sent();
                return [3 /*break*/, 4];
            case 4: return [2 /*return*/, { totalStorageSize: 0, percentOfQuota: 0, usageDetails: '' }];
        }
    });
}); };
export var getDebugConfig = function (config) {
    var debugConfig = __assign({}, config);
    var apiKey = debugConfig.apiKey;
    debugConfig.apiKey = "****".concat(apiKey.substring(apiKey.length - 4));
    return debugConfig;
};
//# sourceMappingURL=helpers.js.map