"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadCollectionMethods = loadCollectionMethods;
var simpl_schema_1 = require("simpl-schema");
var pagination_model_1 = require("../models/pagination.model");
var resolveio_server_app_1 = require("../resolveio-server-app");
var common_1 = require("../util/common");
var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
var INVOICE_COLLECTION = 'invoices';
var SUPPORT_TICKET_COLLECTION = 'support-tickets';
var SUPPORT_TICKET_SYSTEM_USER_ID = 'resolveio';
var SUPPORT_TICKET_SYSTEM_USER = 'ResolveIO';
function coerceDateValue(value) {
    if (value instanceof Date) {
        return value;
    }
    if (typeof value !== 'string' || !ISO_DATE_REGEX.test(value)) {
        return value;
    }
    var parsed = new Date(value);
    return Number.isNaN(parsed.getTime()) ? value : parsed;
}
function coerceDatePath(target, segments) {
    if (!target || !segments.length) {
        return;
    }
    var _a = __read(segments), segment = _a[0], rest = _a.slice(1);
    if (segment === '$') {
        if (Array.isArray(target)) {
            target.forEach(function (item) { return coerceDatePath(item, rest); });
        }
        return;
    }
    if (!Object.prototype.hasOwnProperty.call(target, segment)) {
        return;
    }
    if (rest.length === 0) {
        var updatedValue = coerceDateValue(target[segment]);
        if (updatedValue !== target[segment]) {
            target[segment] = updatedValue;
        }
        return;
    }
    coerceDatePath(target[segment], rest);
}
function coerceDateFields(collectionRef, doc) {
    if (!collectionRef || !collectionRef.simplschema || !doc) {
        return;
    }
    var schema = collectionRef.simplschema;
    var schemaKeys = Object.keys(schema.schema());
    schemaKeys.forEach(function (schemaKey) {
        var _a;
        var definition = schema.schema(schemaKey);
        var typeDefs = (_a = definition === null || definition === void 0 ? void 0 : definition.type) === null || _a === void 0 ? void 0 : _a.definitions;
        if (!typeDefs || !typeDefs.some(function (typeDef) { return typeDef.type === Date; })) {
            return;
        }
        coerceDatePath(doc, schemaKey.split('.'));
    });
}
function normalizeSupportTicketMessage(message) {
    if (!message || typeof message !== 'object' || Array.isArray(message)) {
        return message;
    }
    var normalizedMessage = __assign({}, message);
    var currentIdUser = typeof normalizedMessage.id_user === 'string' ? normalizedMessage.id_user.trim() : '';
    if (currentIdUser) {
        return normalizedMessage;
    }
    var normalizedUser = String(normalizedMessage.user || '').trim().toLowerCase();
    var normalizedType = String(normalizedMessage.type || '').trim().toLowerCase();
    var normalizedSource = String(normalizedMessage.source || '').trim().toLowerCase();
    var normalizedVisibility = String(normalizedMessage.visibility || '').trim().toLowerCase();
    var normalizedBadge = String(normalizedMessage.badge || '').trim().toLowerCase();
    var isInternalSystemMessage = normalizedMessage.internal === true
        || normalizedType === 'resolveio'
        || normalizedType === 'internal'
        || normalizedSource.startsWith('support-')
        || normalizedSource.startsWith('support_')
        || normalizedVisibility === 'internal'
        || normalizedBadge === 'internal'
        || normalizedBadge === 'ai'
        || normalizedUser.startsWith('resolveio');
    if (!isInternalSystemMessage) {
        return normalizedMessage;
    }
    normalizedMessage.id_user = SUPPORT_TICKET_SYSTEM_USER_ID;
    if (!String(normalizedMessage.user || '').trim()) {
        normalizedMessage.user = SUPPORT_TICKET_SYSTEM_USER;
    }
    return normalizedMessage;
}
function roundInvoiceLifecycleDate(value) {
    var parsedValue = coerceDateValue(value);
    if (!(parsedValue instanceof Date) || Number.isNaN(parsedValue.getTime())) {
        return null;
    }
    var roundedDate = new Date(parsedValue);
    roundedDate.setSeconds(0, 0);
    return roundedDate;
}
function normalizeInvoiceLifecycleDates(doc) {
    if (!doc || (doc.status !== 'Invoiced' && doc.status !== 'Paid/Closed')) {
        return;
    }
    var invoiceDate = roundInvoiceLifecycleDate(doc.date_invoice)
        || roundInvoiceLifecycleDate(doc.createdAt)
        || roundInvoiceLifecycleDate(new Date());
    if (!doc.date_invoice && invoiceDate) {
        doc.date_invoice = invoiceDate;
    }
    if (!doc.date_due && doc.date_invoice instanceof Date && !Number.isNaN(doc.date_invoice.getTime())) {
        var dueDate = new Date(doc.date_invoice);
        dueDate.setDate(dueDate.getDate() + 30);
        doc.date_due = dueDate;
    }
}
function normalizeDocumentBeforeReplace(collection, doc) {
    if (!doc) {
        return;
    }
    if (collection === INVOICE_COLLECTION) {
        normalizeInvoiceLifecycleDates(doc);
    }
    if (collection === SUPPORT_TICKET_COLLECTION && Array.isArray(doc.messages)) {
        doc.messages = doc.messages.map(function (message) { return normalizeSupportTicketMessage(message); });
    }
}
function loadCollectionMethods(methodManager) {
    methodManager.methods({
        collectionListAll: {
            function: function () {
                return Promise.resolve(resolveio_server_app_1.ResolveIOServer.getMongoManager().collections().map(function (a) { return a.collectionName; }).sort(function (a, b) { return a.localeCompare(b); }));
            }
        },
        collectionListRB: {
            function: function () {
                return Promise.resolve(resolveio_server_app_1.ResolveIOServer.getMongoManager().collections().filter(function (a) { return a.useRB; }).map(function (a) { return a.collectionName; }).sort(function (a, b) { return a.localeCompare(b); }));
            }
        },
        // Query database for any collection and query
        findOne: {
            bypassSession: true,
            bypassLogs: true,
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                query: {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, query) {
                if (query === void 0) { query = {}; }
                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) {
                    throw new Error('Error in Find One Collection: Invalid collection');
                }
                return resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).findOne(query);
            }
        },
        find: {
            bypassSession: true,
            bypassLogs: true,
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                query: {
                    type: Object,
                    blackbox: true
                },
                sort: {
                    type: Object,
                    blackbox: true,
                    optional: true
                }
            }),
            function: function (collection, query, sortQuery) {
                if (query === void 0) { query = {}; }
                if (sortQuery === void 0) { sortQuery = {}; }
                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) {
                    throw new Error('Error in Find Collection: Invalid collection');
                }
                return resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).find(query, { sort: sortQuery });
            }
        },
        findWithOptions: {
            bypassSession: true,
            bypassLogs: true,
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                query: {
                    type: Object,
                    blackbox: true
                },
                options: {
                    type: pagination_model_1.PaginationOptionsSchema
                }
            }),
            function: function (collection, query, options) {
                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) {
                    throw new Error('Error in Find With Options Collection: Invalid collection');
                }
                else {
                    var optionsQuery = {};
                    if (options.fields && Object.keys(options.fields).length) {
                        optionsQuery['projection'] = options.fields;
                    }
                    if (options.sort && Object.keys(options.sort).length) {
                        optionsQuery['sort'] = options.sort;
                    }
                    if (options.limit) {
                        optionsQuery['limit'] = options.limit;
                    }
                    if (options.skip) {
                        optionsQuery['skip'] = options.skip;
                    }
                    return resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).find(query, optionsQuery);
                }
            }
        },
        // Insert 1 document
        // @Inputs: collection, document
        // @Outputs: res = _id of new document, err = not inserted
        insertDocument: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                document: {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, document) {
                return __awaiter(this, void 0, void 0, function () {
                    var id;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (!!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) return [3 /*break*/, 1];
                                throw new Error('Error in Insert Document Collection: Invalid collection');
                            case 1:
                                id = (0, common_1.objectIdHexString)();
                                document['_id'] = id;
                                document['__v'] = 0;
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).insertOne(document)];
                            case 2:
                                _a.sent();
                                return [2 /*return*/, id];
                        }
                    });
                });
            }
        },
        // Insert 1 document
        // @Inputs: collection, document
        // @Outputs: res = _id of new document, err = not inserted
        insertManyDocuments: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                documents: {
                    type: Array
                },
                'documents.$': {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, documents) {
                return __awaiter(this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (!!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) return [3 /*break*/, 1];
                                throw new Error('Error in Insert Many Documents Collection: Invalid collection');
                            case 1:
                                documents.forEach(function (document) {
                                    document['_id'] = (0, common_1.objectIdHexString)();
                                    document['__v'] = 0;
                                });
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).insertMany(documents)];
                            case 2:
                                _a.sent();
                                return [2 /*return*/, documents.map(function (a) { return a['_id']; })];
                        }
                    });
                });
            }
        },
        // Replaces 1 document with new document (from _id)
        // @Inputs: collection, document id
        // @Outputs: res = 1 (updated 1), err = not updated/wrong version
        // Search for doc, check version, if found then try and update
        updateDocument: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                f_document: {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, f_document) {
                return __awaiter(this, void 0, void 0, function () {
                    var collectionRef;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                collectionRef = resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection);
                                if (!collectionRef) {
                                    throw new Error('Error in Update Document Collection: Invalid collection');
                                }
                                normalizeDocumentBeforeReplace(collection, f_document);
                                coerceDateFields(collectionRef, f_document);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: f_document['_id'] }, f_document)];
                            case 1:
                                _a.sent();
                                return [2 /*return*/, true];
                        }
                    });
                });
            }
        },
        // Updates 1 document's props (from _id)
        // @Inputs: collection, document id, document version, update paramters ({prop: 'xxx', data: 'yyy})
        // @Outputs: res = 1 (updated 1), res = 0 (not updated), err = not updated/wrong version
        // Search for doc, check version, if found then try and update props
        updateDocumentProps: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                doc_id: {
                    type: String
                },
                updateParams: {
                    type: Array
                },
                'updateParams.$': {
                    type: Object,
                    blackbox: true
                },
                doc__v: {
                    type: Number,
                    optional: true
                }
            }),
            function: function (collection, doc_id, updateParams, doc__v) {
                return __awaiter(this, void 0, void 0, function () {
                    var collectionRef, currDoc, modifiedDoc_1, oldDoc, newCurrDocId, newCurrDocV, updatedDoc;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                collectionRef = resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection);
                                if (!!collectionRef) return [3 /*break*/, 1];
                                throw new Error('Error in Update Document Props Collection: Invalid collection');
                            case 1: return [4 /*yield*/, collectionRef.findOne({ _id: doc_id })];
                            case 2:
                                currDoc = _a.sent();
                                if (!currDoc) return [3 /*break*/, 11];
                                modifiedDoc_1 = (0, common_1.deepCopy)(currDoc);
                                updateParams.forEach(function (data) {
                                    modifiedDoc_1[data.prop] = data.data;
                                });
                                if (!(!doc__v || modifiedDoc_1.__v === doc__v)) return [3 /*break*/, 4];
                                normalizeDocumentBeforeReplace(collection, modifiedDoc_1);
                                coerceDateFields(collectionRef, modifiedDoc_1);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: modifiedDoc_1._id }, modifiedDoc_1, {}, false, false, currDoc)];
                            case 3:
                                _a.sent();
                                return [3 /*break*/, 10];
                            case 4:
                                console.log(new Date(), 'invalid version - ' + collection, currDoc.__v, doc__v);
                                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection + '.versions')) return [3 /*break*/, 9];
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection + '.versions').findOne({
                                        _id: {
                                            _id: currDoc._id,
                                            __v: doc__v
                                        }
                                    })];
                            case 5:
                                oldDoc = _a.sent();
                                newCurrDocId = currDoc._id;
                                newCurrDocV = currDoc.__v;
                                if (!oldDoc) return [3 /*break*/, 7];
                                updatedDoc = (0, common_1.getMongoMergeUpdatedDoc)(modifiedDoc_1, currDoc, oldDoc);
                                updatedDoc._id = newCurrDocId;
                                updatedDoc.__v = newCurrDocV;
                                currDoc._id = newCurrDocId;
                                currDoc.__v = newCurrDocV;
                                normalizeDocumentBeforeReplace(collection, updatedDoc);
                                coerceDateFields(collectionRef, updatedDoc);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: newCurrDocId }, updatedDoc, {}, false, false, currDoc)];
                            case 6:
                                _a.sent();
                                return [3 /*break*/, 8];
                            case 7:
                                // throw new Error('Error In Update Document Props Collections: Invalid Version And Could Not Find History Props - DB: ' + newCurrDocV + ', Trying to update with :' + doc__v);
                                console.log(new Date(), 'Error In Update Document Props Collections: Invalid Version And Could Not Find History Props - DB: ' + newCurrDocV + ', Trying to update with :' + doc__v);
                                _a.label = 8;
                            case 8: return [3 /*break*/, 10];
                            case 9: throw new Error('Error In Update Document Props Collections: Invalid Version And We Are NOT Using Versions On This Collection!');
                            case 10: return [3 /*break*/, 12];
                            case 11: throw new Error('Error in Update Document Props Collections: No Document');
                            case 12: return [2 /*return*/, true];
                        }
                    });
                });
            }
        },
        updateDocumentOffline: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                f_document: {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, f_document) {
                return __awaiter(this, void 0, void 0, function () {
                    var collectionRef, currDoc, newCurrDocId, newCurrDocV, oldDocV, oldDoc, updatedDoc;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                collectionRef = resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection);
                                if (!!collectionRef) return [3 /*break*/, 1];
                                throw new Error('Error in Update Document Offline Collection: Invalid collection');
                            case 1: return [4 /*yield*/, collectionRef.findOne({ _id: f_document['_id'] })];
                            case 2:
                                currDoc = _a.sent();
                                if (!currDoc) return [3 /*break*/, 11];
                                if (!(currDoc.__v === f_document['__v'])) return [3 /*break*/, 4];
                                normalizeDocumentBeforeReplace(collection, f_document);
                                coerceDateFields(collectionRef, f_document);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: f_document['_id'] }, f_document, {}, false, false, currDoc)];
                            case 3:
                                _a.sent();
                                return [3 /*break*/, 10];
                            case 4:
                                console.log('OFFLINE - invalid version - ' + collection, currDoc.__v, f_document['__v']);
                                newCurrDocId = currDoc._id;
                                newCurrDocV = currDoc.__v;
                                oldDocV = f_document['__v'];
                                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection + '.versions')) return [3 /*break*/, 9];
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection + '.versions').findOne({
                                        _id: {
                                            _id: newCurrDocId,
                                            __v: oldDocV
                                        }
                                    })];
                            case 5:
                                oldDoc = _a.sent();
                                if (!oldDoc) return [3 /*break*/, 7];
                                updatedDoc = (0, common_1.getMongoMergeUpdatedDoc)(f_document, currDoc, oldDoc);
                                updatedDoc._id = newCurrDocId;
                                updatedDoc.__v = newCurrDocV;
                                currDoc._id = newCurrDocId;
                                currDoc.__v = newCurrDocV;
                                normalizeDocumentBeforeReplace(collection, updatedDoc);
                                coerceDateFields(collectionRef, updatedDoc);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: newCurrDocId }, updatedDoc, {}, false, false, currDoc)];
                            case 6:
                                _a.sent();
                                return [3 /*break*/, 8];
                            case 7: throw new Error('Error in Update Document Offline Collections: OFFLINE - Invalid Version And Could Not Find History Props - DB: ' + newCurrDocV + ', Trying to update with :' + oldDocV);
                            case 8: return [3 /*break*/, 10];
                            case 9: throw new Error('Error in Update Document Offline Collections: Invalid Version And We Are NOT Using Versions On This Collection!');
                            case 10: return [3 /*break*/, 12];
                            case 11: throw new Error('Error in Update Document Offline Collections: No Document');
                            case 12: return [2 /*return*/, true];
                        }
                    });
                });
            }
        },
        // Updates 1 document's props (from _id)
        // @Inputs: collection, document id, document version, update paramters ({prop: 'xxx', data: 'yyy})
        // @Outputs: res = 1 (updated 1), res = 0 (not updated), err = not updated/wrong version
        // Search for doc, check version, if found then try and update props
        updateDocumentPropsOffline: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                doc_id: {
                    type: String
                },
                updateParams: {
                    type: Array
                },
                'updateParams.$': {
                    type: Object,
                    blackbox: true
                },
                doc__v: {
                    type: Number
                }
            }),
            function: function (collection, doc_id, updateParams, doc__v) {
                return __awaiter(this, void 0, void 0, function () {
                    var collectionRef, currDoc, modifiedDoc_2, newCurrDocId, newCurrDocV, oldDoc, updatedDoc;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                collectionRef = resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection);
                                if (!!collectionRef) return [3 /*break*/, 1];
                                throw new Error('Error in Update Document Props Offline Collection: Invalid collection');
                            case 1: return [4 /*yield*/, collectionRef.findOne({ _id: doc_id }, null, true)];
                            case 2:
                                currDoc = _a.sent();
                                if (!currDoc) return [3 /*break*/, 11];
                                modifiedDoc_2 = (0, common_1.deepCopy)(currDoc);
                                updateParams.forEach(function (data) {
                                    modifiedDoc_2[data.prop] = data.data;
                                });
                                if (!(modifiedDoc_2.__v === doc__v)) return [3 /*break*/, 4];
                                normalizeDocumentBeforeReplace(collection, modifiedDoc_2);
                                coerceDateFields(collectionRef, modifiedDoc_2);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: modifiedDoc_2._id }, modifiedDoc_2, {}, false, false, currDoc)];
                            case 3:
                                _a.sent();
                                return [3 /*break*/, 10];
                            case 4:
                                console.log('OFFLINE - invalid version - ' + collection, currDoc.__v, doc__v);
                                newCurrDocId = currDoc._id;
                                newCurrDocV = currDoc.__v;
                                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection + '.versions')) return [3 /*break*/, 9];
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection + '.versions').findOne({
                                        _id: {
                                            _id: currDoc._id,
                                            __v: doc__v
                                        }
                                    })];
                            case 5:
                                oldDoc = _a.sent();
                                if (!oldDoc) return [3 /*break*/, 7];
                                updatedDoc = (0, common_1.getMongoMergeUpdatedDoc)(modifiedDoc_2, currDoc, oldDoc);
                                updatedDoc._id = newCurrDocId;
                                updatedDoc.__v = newCurrDocV;
                                currDoc._id = newCurrDocId;
                                currDoc.__v = newCurrDocV;
                                normalizeDocumentBeforeReplace(collection, updatedDoc);
                                coerceDateFields(collectionRef, updatedDoc);
                                return [4 /*yield*/, collectionRef.replaceOne({ _id: newCurrDocId }, updatedDoc, {}, false, false, currDoc)];
                            case 6:
                                _a.sent();
                                return [3 /*break*/, 8];
                            case 7: throw new Error('Error in Update Document Props Offline Collections: OFFLINE - Invalid Version And Could Not Find History Props - DB: ' + newCurrDocV + ', Trying to update with :' + doc__v);
                            case 8: return [3 /*break*/, 10];
                            case 9: throw new Error('Error in Update Document Props Offline Collections: Invalid Version And We Are NOT Using Versions On This Collection!');
                            case 10: return [3 /*break*/, 12];
                            case 11: throw new Error('Error in Update Document Props Offline Collections: No Document');
                            case 12: return [2 /*return*/, true];
                        }
                    });
                });
            }
        },
        // Removes 1 document (from _id)
        // @Inputs: collection, document id
        // @Outputs: res = 1 (deleted), res = 0 (not deleted), err = not deleted
        // Search for doc, if found then try and remove
        removeDocument: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                doc_id: {
                    type: String
                }
            }),
            function: function (collection, doc_id) {
                return __awaiter(this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) {
                                    throw new Error('Error in Remove Document Collection: Invalid collection');
                                }
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).deleteOne({ _id: doc_id })];
                            case 1:
                                _a.sent();
                                return [2 /*return*/, true];
                        }
                    });
                });
            }
        },
        removeDocumentWithQuery: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                query: {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, query) {
                return __awaiter(this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) {
                                    throw new Error('Error in Remove Document With Query Collection: Invalid collection');
                                }
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).deleteOne(query)];
                            case 1:
                                _a.sent();
                                return [2 /*return*/, true];
                        }
                    });
                });
            }
        },
        removeDocumentsWithQuery: {
            check: new simpl_schema_1.default({
                collection: {
                    type: String
                },
                query: {
                    type: Object,
                    blackbox: true
                }
            }),
            function: function (collection, query) {
                return __awaiter(this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (!resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection)) {
                                    throw new Error('Error in Remove Documents With Query Collections: Invalid Collection');
                                }
                                return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().collection(collection).deleteMany(query)];
                            case 1:
                                _a.sent();
                                return [2 /*return*/, true];
                        }
                    });
                });
            }
        }
    });
}

//# sourceMappingURL=collections.js.map
