var jsongMerge = require('./../cache/jsongMerge');
var pathValueMerge = require('./../cache/pathValueMerge');
var isJSONG = require('./../support/isJSONG');
var isMessage = require('./../support/isMessage');
module.exports = mergeCacheAndGatherRefsAndInvalidations;

/**
 * takes the response from an action and merges it into the
 * cache.  Anything that is an invalidation will be added to
 * the first index of the return value, and the inserted refs
 * are the second index of the return value.  The third index
 * of the return value is messages from the action handlers
 *
 * @param {Object} cache
 * @param {Array} jsongOrPVs
 */
function mergeCacheAndGatherRefsAndInvalidations(cache, jsongOrPVs) {
    var references = [];
    var len = -1;
    var invalidations = [];
    var messages = [];
    var values = [];

    jsongOrPVs.forEach(function(jsongOrPV) {
        var refsAndValues = [];

        if (isMessage(jsongOrPV)) {
            messages[messages.length] = jsongOrPV;
        }

        else if (isJSONG(jsongOrPV)) {
            refsAndValues = jsongMerge(cache, jsongOrPV);
        }

        // Last option are path values.
        else {
            refsAndValues = pathValueMerge(cache, jsongOrPV);
        }

        var refs = refsAndValues.references;
        var vals = refsAndValues.values;
        var invs = refsAndValues.invalidations;

        if (vals && vals.length) {
            values = values.concat(vals);
        }

        if (invs && invs.length) {
            invalidations = invalidations.concat(invs);
        }

        if (refs && refs.length) {
            refs.forEach(function(ref) {
                references[++len] = ref;
            });
        }
    });

    return {
        invalidations: invalidations,
        references: references,
        messages: messages,
        values: values
    };
}
