'use strict';

var q = require("q");
var MongoConnection = require('./MongoConnection');
var logger = require('../../../utils/Logger').loggers.get('db');
var ElasticIndexingService= require('../../../search/ElasticIndexingService');
var ObjectID = require('mongodb').ObjectID;


function update(params){
    var deferred = q.defer();

    var documentId = params.documentId;
    var finalDocumentIndexingId = params.finalDocumentIndexingId;
    var updateDocument = params.updateDocument;
    var versionDocuments = params.versionDocuments;
    var connectionName = params.connectionName;

    MongoConnection.getCollection(function (err, collection) {
        if (err) {
            logger.error(err);
            deferred.reject(err);
        } else {

            // updates are sent in a batch so that the chance of one operation happening without the other are mimimized. It also
            // makes things faster
            var batch = collection.initializeOrderedBulkOp();

            // prevent updating of _id
            delete updateDocument._id;

            if (updateDocument.systemHeader.currentVersion) {
                batch.find({ 'documentId': documentId, 'systemHeader.currentVersion': true }).updateOne(updateDocument);
            } else {
                batch.insert(updateDocument, {w: 1});
            }

            for(var k = 0 ; k < versionDocuments.length ; k++){
                var version = versionDocuments[k];
                var options = {
                    w: 1 // ensure a safe write
                };

                logger.info("Inserting previous version "
                    + version.systemHeader.versionId
                    + " for document " + version.documentId);

                // this should use insert - it previously used upsert but this won't work with the elastic indexing where the
                // _id must match between ElasticSearch and MongoDB
                batch.insert(version, options);
            }
            batch.execute(function(err, results){
                if (err){
                    deferred.reject(new Error(err));
                }
                else{
                    deferred.resolve(results);
                }
            });
        }
    }, connectionName);

    return deferred.promise;
}

function getIndexId(document){
    return document._id.toHexString();
}

function setVersionDocumentId(document) {
    document._id = new ObjectID();
    return document;
}

function getVersionIndexId(document){
    return getIndexId(document);
}


module.exports = {

    update: update,

    getIndexId: getIndexId,

    getLoadVersionQuery: function(versionId){

        var query = {'systemHeader.versionId': versionId};
        var sortQuery = {'systemHeader.createdDate': -1};

        return {query : query, sortQuery: sortQuery};
    },

    setVersionDocumentId: setVersionDocumentId,

    getVersionIndexId: getVersionIndexId

};
