"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractSchema = extractSchema;
const encryption_functions_1 = require("./encryption-functions");
function extractSchema(eventProperties, encryptionSession) {
    if (!eventProperties) {
        return [];
    }
    const visited = new WeakSet();
    const mapping = (obj) => {
        if (Array.isArray(obj)) {
            if (visited.has(obj)) {
                return 'list';
            }
            visited.add(obj);
            const list = obj.map((x) => {
                return mapping(x);
            });
            return removeDuplicates(list);
        }
        else if (typeof obj === 'object' && obj !== null) {
            if (visited.has(obj)) {
                return 'object';
            }
            visited.add(obj);
            const mappedResult = [];
            for (const [key, val] of Object.entries(obj)) {
                const mappedEntry = {
                    propertyName: key,
                    propertyType: getPropValueType(val)
                };
                if (typeof val === 'object' && val != null) {
                    mappedEntry.children = mapping(val);
                }
                else if (val !== undefined && val !== null) {
                    const encryptedValue = getEncryptedPropertyValueIfEnabled(val, encryptionSession);
                    if (encryptedValue !== undefined) {
                        mappedEntry.encryptedPropertyValue = encryptedValue;
                    }
                }
                mappedResult.push(mappedEntry);
            }
            return mappedResult;
        }
        else {
            return getPropValueType(obj);
        }
    };
    const mappedEventProps = mapping(eventProperties);
    return mappedEventProps;
}
function getEncryptedPropertyValueIfEnabled(propertyValue, session) {
    if (!session) {
        return undefined;
    }
    try {
        return (0, encryption_functions_1.encryptValueWithSession)(propertyValue, session);
    }
    catch (error) {
        return undefined;
    }
}
function removeDuplicates(array) {
    const uniqueItems = new Set();
    const result = [];
    for (const item of array) {
        let stringRep;
        if (typeof item === 'object' && item !== null) {
            stringRep = JSON.stringify(item, Object.keys(item).sort());
        }
        else {
            stringRep = typeof item + ':' + String(item);
        }
        if (!uniqueItems.has(stringRep)) {
            uniqueItems.add(stringRep);
            result.push(item);
        }
    }
    return result;
}
function getPropValueType(propValue) {
    const propType = typeof propValue;
    if (propValue == null) {
        return 'null';
    }
    else if (propType === 'string') {
        return 'string';
    }
    else if (propType === 'number' || propType === 'bigint') {
        if ((propValue + '').includes('.')) {
            return 'float';
        }
        else {
            return 'int';
        }
    }
    else if (propType === 'boolean') {
        return 'boolean';
    }
    else if (propType === 'object') {
        if (Array.isArray(propValue)) {
            return 'list';
        }
        else {
            return 'object';
        }
    }
    else {
        return 'unknown';
    }
}
//# sourceMappingURL=schema-functions.js.map