'use strict';

var jsonPatch = require('rfc6902');
var lodashLang = require('lodash/lang');
var SystemHeaderFilter = require('../data/SystemHeaderFilter');
var SharedConstants = require('../constants/SharedConstants');

const lodashCloneDeep = require('lodash.clonedeep');

/**
 * do any functions that are specific to a system type like clearing the document from the cache
 * @param document
 * @param updateDoc
 */
function performSystemTypeUpdateOperations(document, updateDoc) {
    if (document.systemHeader.systemType === SharedConstants.SYSTEM_TYPE_ACCOUNT && !updateDoc.pass) {
        updateDoc.pass = document.pass;
    }
}

/**
 * simple update - non deep
 * @param document
 * @param updateDoc
 */
function applySimpleUpdates(document, updateDoc) {
    if (updateDoc) {
        // perform any operations specific to a systemType
        performSystemTypeUpdateOperations(document, updateDoc);

        // set the values in the updateDoc in the existing currentDocument
        var updateKeys = Object.keys(updateDoc);
        for (var i = 0; i < updateKeys.length; i++) {
            var fieldName = updateKeys[i];
            if (fieldName === "systemHeader") {
                SystemHeaderFilter.applyUpdatesToSystemHeader(document, updateDoc);
            } else {
                var value = updateDoc[fieldName];
                document[fieldName] = value;
            }
        }
    }
}

// get the updates by comparing the doc and original doc
function getUpdates(originalDoc, doc) {
    logger.info("Determining fields that have changed in update");

    var changes = originalDoc ? jsonPatch.createPatch(originalDoc, doc) : [];

    var result = {
        updates: changes,
        documentId: doc.documentId
    };

    return result;
}

function applyUpdates(document, updateData) {
    if (updateData.updates) {
        jsonPatch.applyPatch(document, updateData.updates);
    }
}

function applyUpdatesDeepDiff(document, updateDoc) {

    SystemHeaderFilter.applyUpdatesToSystemHeader(document, updateDoc);

    if (updateDoc.systemHeader) {
        updateDoc.systemHeader = lodashCloneDeep(document.systemHeader);
    }

    // perform any operations specific to a systemType
    performSystemTypeUpdateOperations(document, updateDoc);

    var updates = getUpdates(document, updateDoc);
    applyUpdates(document, updates);
}

module.exports = {

    getUpdates: getUpdates,

    applyUpdates: applyUpdates,

    applyUpdatesDeepDiff: applyUpdatesDeepDiff,

    applyUpdatesSimple: applySimpleUpdates
};
