"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deserializeConnectOptions = exports.serializeConnectOptions = exports.deserializeEvaluationResult = exports.serializeEvaluationResult = exports.SerializedResultTypes = exports.deserializeError = exports.serializeError = void 0;
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');
    return keys.reduce((acc, key) => {
        acc[key] = err[key];
        return acc;
    }, {});
}
exports.serializeError = serializeError;
function deserializeError(err) {
    return Object.assign(new Error(), err);
}
exports.deserializeError = deserializeError;
var SerializedResultTypes;
(function (SerializedResultTypes) {
    SerializedResultTypes["SerializedErrorResult"] = "SerializedErrorResult";
    SerializedResultTypes["InspectResult"] = "InspectResult";
    SerializedResultTypes["SerializedShellApiResult"] = "SerializedShellApiResult";
})(SerializedResultTypes || (exports.SerializedResultTypes = SerializedResultTypes = {}));
function serializeEvaluationResult({ type, printable, source, }) {
    if (isPrimitive(printable)) {
        return { type, printable, source };
    }
    if (isError(printable)) {
        return {
            type: SerializedResultTypes.SerializedErrorResult,
            printable: serializeError(printable),
            source,
        };
    }
    if (type === null) {
        return {
            type: SerializedResultTypes.InspectResult,
            printable: (0, util_1.inspect)(printable),
            source,
        };
    }
    return {
        type: SerializedResultTypes.SerializedShellApiResult,
        printable: {
            origType: type,
            serializedValue: bson_1.EJSON.serialize(printable),
        },
    };
}
exports.serializeEvaluationResult = serializeEvaluationResult;
function deserializeEvaluationResult({ type, printable, source, }) {
    if (type === SerializedResultTypes.SerializedErrorResult) {
        return { type, printable: deserializeError(printable), source };
    }
    if (type === SerializedResultTypes.SerializedShellApiResult) {
        return {
            type: printable.origType,
            printable: bson_1.EJSON.deserialize(printable.serializedValue),
            source,
        };
    }
    return { type, printable, source };
}
exports.deserializeEvaluationResult = deserializeEvaluationResult;
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;
}
exports.serializeConnectOptions = serializeConnectOptions;
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;
}
exports.deserializeConnectOptions = deserializeConnectOptions;
//# sourceMappingURL=serializer.js.map