"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.serializeError = serializeError;
exports.deserializeError = deserializeError;
exports.serializeEvaluationResult = serializeEvaluationResult;
exports.deserializeEvaluationResult = deserializeEvaluationResult;
exports.serializeConnectOptions = serializeConnectOptions;
exports.deserializeConnectOptions = deserializeConnectOptions;
const util_1 = require("util");
const bson_1 = require("bson");
function isPrimitive(val) {
    return (typeof val !== 'object' && typeof val !== 'function') || val === null;
}
function isError(val) {
    return val && val.name && val.message && val.stack;
}
function getNames(obj) {
    return Object.getOwnPropertyNames(obj);
}
function serializeError(err) {
    const keys = getNames(err)
        .concat('name')
        .filter((key) => typeof err[key] !== 'function');
    return keys.reduce((acc, key) => {
        acc[key] = err[key];
        return acc;
    }, {});
}
function deserializeError(err) {
    return Object.assign(new Error(), err);
}
function serializeEvaluationResult({ type, printable, source, constructionOptions, }) {
    if (isPrimitive(printable)) {
        return { type, printable, source, constructionOptions };
    }
    if (isError(printable)) {
        return {
            type: 'SerializedErrorResult',
            printable: serializeError(printable),
            source,
            constructionOptions,
        };
    }
    if (type === null) {
        return {
            type: 'InspectResult',
            printable: (0, util_1.inspect)(printable),
            source,
        };
    }
    return {
        type: 'SerializedShellApiResult',
        printable: {
            origType: type,
            serializedValue: bson_1.EJSON.serialize(printable),
            constructionOptions,
        },
    };
}
function deserializeEvaluationResult({ type, printable, source, constructionOptions, }) {
    if (type === 'SerializedErrorResult') {
        return {
            type,
            printable: deserializeError(printable),
            source,
            constructionOptions,
        };
    }
    if (type === 'SerializedShellApiResult') {
        return {
            type: printable.origType,
            printable: bson_1.EJSON.deserialize(printable.serializedValue),
            source,
            constructionOptions,
        };
    }
    return { type, printable, source, constructionOptions };
}
const autoEncryptionBSONOptions = ['schemaMap', 'encryptedFieldsMap'];
function serializeConnectOptions(options) {
    var _a;
    const serializedOptions = { ...options };
    for (const autoEncryptionOption of autoEncryptionBSONOptions) {
        if ((_a = serializedOptions.autoEncryption) === null || _a === void 0 ? void 0 : _a[autoEncryptionOption]) {
            serializedOptions.autoEncryption = {
                ...serializedOptions.autoEncryption,
                [autoEncryptionOption]: bson_1.EJSON.serialize(serializedOptions.autoEncryption[autoEncryptionOption], { relaxed: false }),
            };
        }
    }
    return serializedOptions;
}
function deserializeConnectOptions(options) {
    var _a;
    const deserializedOptions = { ...options };
    for (const autoEncryptionOption of autoEncryptionBSONOptions) {
        if ((_a = deserializedOptions.autoEncryption) === null || _a === void 0 ? void 0 : _a[autoEncryptionOption]) {
            deserializedOptions.autoEncryption = {
                ...deserializedOptions.autoEncryption,
                [autoEncryptionOption]: bson_1.EJSON.deserialize(deserializedOptions.autoEncryption[autoEncryptionOption], { relaxed: false }),
            };
        }
    }
    return deserializedOptions;
}
//# sourceMappingURL=serializer.js.map