'use strict';

var mongoose = require('mongoose')
    , Query    = mongoose.Query
    , crypto = require("crypto");
var defaultExclude = ["_id"];
function hashObject(model, exclude){
    exclude = exclude.concat(defaultExclude);
    var obj = model.toObject();

    for(var i in exclude){
        var key = exclude[i];
        if(key.indexOf(".") != -1){
            var deep = key.split(".");
            var last = deep.pop();
            var token = obj;
            for(var j in deep){
                token = token[deep[j]];
            }
            token[last] = undefined;
        }else{
            obj[key] = undefined;
        }
    }
    return crypto.createHash('sha1').update(JSON.stringify(obj)).digest('Base64')
}
function hashIncludeOnlyObject(model, include){
    var obj = model.toObject();
    var hashObject = {}
    for(var i in include){
        var key = include[i];
        if(key.indexOf(".") != -1){
            var deep = key.split(".");
            var last = deep.pop();
            var token = obj;
            for(var j in deep){
                token = token[deep[j]];
            }
            hashObject[key] = token[last]
        }else{
            hashObject[key] = obj[key];
        }
    }
    return crypto.createHash('sha1').update(JSON.stringify(hashObject)).digest('Base64')
}
module.exports.getPluginWithOptions = function(options){

    options.sparse = options.sparse || false;
    options.dropDups = options.dropDups || false;
    return function(schema) {

        schema.add({ sha1_hash: {type:String, unique:true, sparse:options.sparse, dropDups:options.dropDups} });

        schema.pre('save', function (next) {
            if(options.includeOnly){
                this.sha1_hash = hashIncludeOnlyObject(this, options.includeOnly);
            }else{
                this.sha1_hash = hashObject(this, options.exclude);
            }
            next();
        });
    }
};
