"use strict";
/**
 * Delta data access
 *
 *  Copyright (C) 2010-2019 R-T Specialty, LLC.
 *
 *  This file is part of the Liza Data Collection Framework.
 *
 *  liza is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Get deltas from the mongo document in order to process and publish them
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.MongoDeltaDao = void 0;
var ContextError_1 = require("../../error/ContextError");
var DaoError_1 = require("../../error/DaoError");
/** Manage deltas */
var MongoDeltaDao = /** @class */ (function () {
    /**
     * Initialize connection
     *
     * @param _collection - Mongo db collection
     */
    function MongoDeltaDao(_collection, _env) {
        this._collection = _collection;
        this._env = _env;
        /** The document fields to read */
        this.RESULT_FIELDS = {
            id: 1,
            programId: 1,
            agentName: 1,
            agentEntityId: 1,
            startDate: 1,
            lastUpdate: 1,
            quoteExpDate: 1,
            quoteSetId: 1,
            data: 1,
            ratedata: 1,
            rdelta: 1,
            topSavedStepId: 1,
            deltaPublishedTs: 1,
        };
    }
    /**
     * Get documents in need of processing
     *
     * @return documents in need of processing
     */
    MongoDeltaDao.prototype.getUnprocessedDocuments = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            // documents that have rates pending should not be processed yet
            _this._collection.find({
                published: false,
                deltaError: { $ne: true },
                'ratedata.__rate_pending': { $in: [[0], null] },
                env: _this._env,
            }, { fields: _this.RESULT_FIELDS }, function (e, cursor) {
                if (e) {
                    reject(new DaoError_1.DaoError('Error fetching unprocessed documents: ' + e));
                    return;
                }
                cursor.toArray(function (e, data) {
                    if (e) {
                        reject(new DaoError_1.DaoError('Error fetching array from cursor: ' + e));
                        return;
                    }
                    resolve(data);
                });
            });
        });
    };
    /**
     * Update the last published timestamp
     *
     * @param doc_id - Document to update
     * @param type   - Delta type
     * @param ts     - Timestamp to set
     */
    MongoDeltaDao.prototype.setPublishedTs = function (doc_id, type, ts) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            var set_data = {};
            set_data['deltaPublishedTs.' + type] = ts;
            _this._collection.update({ id: doc_id }, { $set: set_data }, { upsert: false }, function (e) {
                if (e) {
                    reject(ContextError_1.context(new DaoError_1.DaoError('Error updating published ts: ' + e), {
                        doc_id: doc_id,
                        quote_id: doc_id,
                    }));
                    return;
                }
                resolve();
            });
        });
    };
    /**
     * Mark a given document as processed.
     *
     * First does a check to make sure that
     * the document does not have a newer update timestamp than the provided one
     *
     * @param doc_id         - The document to mark
     * @param last_update_ts - The last time this document was updated
     */
    MongoDeltaDao.prototype.markDocumentAsProcessed = function (doc_id, last_update_ts) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this._collection.update({ id: doc_id, lastUpdate: { $lte: last_update_ts } }, { $set: { published: true } }, { upsert: false }, function (e) {
                if (e) {
                    reject(ContextError_1.context(new DaoError_1.DaoError('Error marking document as processed: ' + e), {
                        doc_id: doc_id,
                        quote_id: doc_id,
                        last_update_ts: last_update_ts,
                    }));
                    return;
                }
                resolve();
                return;
            });
        });
    };
    /**
     * Flag the document as being in an error state
     *
     * @param doc_id - The document to flag
     *
     * @return any errors that occurred
     */
    MongoDeltaDao.prototype.setErrorFlag = function (doc_id) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this._collection.update({ id: doc_id }, { $set: { deltaError: true } }, { upsert: false }, function (e) {
                if (e) {
                    reject(ContextError_1.context(new DaoError_1.DaoError('Failed setting error flag: ' + e), {
                        doc_id: doc_id,
                        quote_id: doc_id,
                    }));
                    return;
                }
                resolve();
                return;
            });
        });
    };
    /**
     * Get a count of documents in an error state
     *
     * @return a count of the documents in an error state
     */
    MongoDeltaDao.prototype.getErrorCount = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this._collection.find({
                deltaError: true,
                env: _this._env,
            }, {}, function (e, cursor) {
                if (e) {
                    reject(new Error('Failed getting error count: ' + e));
                    return;
                }
                cursor.toArray(function (e, data) {
                    if (e) {
                        reject(ContextError_1.context(new DaoError_1.DaoError('Failed getting error count: ' + e), {
                            cursor: cursor,
                        }));
                        return;
                    }
                    resolve(data.length);
                });
            });
        });
    };
    /** The ratedata delta type */
    MongoDeltaDao.DELTA_RATEDATA = 'ratedata';
    /** The data delta type */
    MongoDeltaDao.DELTA_DATA = 'data';
    return MongoDeltaDao;
}());
exports.MongoDeltaDao = MongoDeltaDao;
//# sourceMappingURL=data:application/json;base64, 