"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nativePick = exports.safeDecodeURIComponent = exports.LiteralObject = exports.LiteralJSONStringify = exports.getLanguageString = exports.isEmpty = exports.isPlainObject = void 0;
const uuid_1 = require("../lib/uuid");
/**
 * Helper function to determine if a given input is an Object.
 * @param v - The value to check.
 * @return {Boolean}
 */
function isPlainObject(v) {
    return v && Object.getPrototypeOf(v) === Object.getPrototypeOf({});
}
exports.isPlainObject = isPlainObject;
/**
 * Helper function to determine if a Object is empty.
 * @param obj - The object to check.
 * @return {Boolean}
 */
function isEmpty(obj) {
    return Object.keys(obj).length === 0;
}
exports.isEmpty = isEmpty;
/**
 * Helper function to retrieve preferred language from browser language header.
 * @param language - The language header string.
 * @return {string}
 */
function getLanguageString(language) {
    return language?.split(/[,;]/)[0].toLowerCase();
}
exports.getLanguageString = getLanguageString;
/**
 * Custom encoder for JSON.stringify to replace function strings with literal JS.
 * @param {Object} obj
 * @return {string}
 */
function LiteralJSONStringify(obj) {
    const fns = [];
    const seen = new WeakSet();
    const jsonString = JSON.stringify(obj, function (key, value) {
        // Replace circular references with a string
        if (typeof value === 'object' && value !== null) {
            if (seen.has(value)) {
                return '[circular reference]';
            }
            seen.add(value);
        }
        if (typeof value === 'object' &&
            value !== null &&
            value.webManifestValueType) {
            const valueType = value.webManifestValueType;
            value = value.webManifestValue;
            if (valueType !== 'function') {
                throw new Error(`Unsupported webManifestValueType: ${valueType}`);
            }
            if (typeof value !== 'string') {
                throw new Error(`webManifestValue should be a string`);
            }
            const id = (0, uuid_1.generate)();
            fns.push([id, value]);
            return id;
        }
        else if (value instanceof Set) {
            return Array.from(value.values());
        }
        else if (value instanceof Map) {
            return Array.from(value.entries());
        }
        return value;
    });
    return fns.reduce(function (acc, entry) {
        return acc.replace(new RegExp(`"${entry[0]}"`, 'g'), entry[1]);
    }, jsonString);
}
exports.LiteralJSONStringify = LiteralJSONStringify;
/**
 * Generate a literal object to be used in the web manifest.
 *
 * @param {string} literalValue
 * @returns
 */
function LiteralObject(literalValue) {
    if (typeof literalValue !== 'string') {
        throw new Error(`webManifestValue should be a string`);
    }
    return {
        webManifestValueType: 'function',
        webManifestValue: literalValue,
    };
}
exports.LiteralObject = LiteralObject;
/**
 * Try to decode string as if it's an encoded string. If it's malformed return the string.
 *
 * Ported from https://github.com/optimizely/client-js/blob/b6c889607f8e185575264521576225789591326e/src/core/utils/cookie.js#L59-L70
 *
 * @param {string} str
 * @returns {string}
 */
function safeDecodeURIComponent(str) {
    try {
        return decodeURIComponent(str);
    }
    catch (e) {
        return str;
    }
}
exports.safeDecodeURIComponent = safeDecodeURIComponent;
/**
 * From https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore?tab=readme-ov-file#_pick
 *
 * @param {*} object
 * @param {*} keys
 * @returns
 */
function nativePick(object, keys) {
    return keys.reduce((obj, key) => {
        if (object && object.hasOwnProperty(key)) {
            obj[key] = object[key];
        }
        return obj;
    }, {});
}
exports.nativePick = nativePick;
exports.default = {
    isPlainObject,
    isEmpty,
    getLanguageString,
    LiteralJSONStringify,
    safeDecodeURIComponent,
    nativePick,
};
