// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// In-memory implementation of Collection.
// TODO(sadovsky): Replace with nedb NPM module.

'use strict';

var _ = require('lodash');
var inherits = require('inherits');

var Collection = require('./collection');

inherits(MemCollection, Collection);
module.exports = MemCollection;

function MemCollection(name) {
  Collection.call(this);
  this.name_ = name;
  this.vals_ = [];
}

function noop() {}

MemCollection.prototype.find = function(q, opts, cb) {
  var that = this;
  cb = cb || noop;
  q = this.normalize_(q);
  var res = _.filter(this.vals_, function(v) {
    return that.matches_(v, q);
  });
  if (opts.sort) {
    // Note, we make various simplifying assumptions.
    var keys = _.keys(opts.sort);
    console.assert(keys.length === 1);
    var key = keys[0];
    console.assert(opts.sort[key] === 1);
    res = _.sortBy(res, key);
  }
  process.nextTick(function() {
    cb(null, _.cloneDeep(res));
  });
};

MemCollection.prototype.insert = function(v, cb) {
  var that = this;
  cb = cb || noop;
  console.assert(!v._id);
  v = _.assign({}, v, {_id: String(this.vals_.length)});
  this.vals_.push(v);
  process.nextTick(function() {
    that.emit('change');
    cb(null, v._id);
  });
};

MemCollection.prototype.remove = function(q, cb) {
  var that = this;
  cb = cb || noop;
  q = this.normalize_(q);
  this.vals_ = _.filter(this.vals_, function(v) {
    return !that.matches_(v, q);
  });
  process.nextTick(function() {
    that.emit('change');
    cb();
  });
};

MemCollection.prototype.update = function(q, opts, cb) {
  var that = this;
  cb = cb || noop;
  q = this.normalize_(q);
  var vals = _.filter(this.vals_, function(v) {
    return that.matches_(v, q);
  });

  // Note, we make various simplifying assumptions.
  var keys = _.keys(opts);
  console.assert(keys.length === 1);
  var key = keys[0];
  console.assert(_.contains(['$addToSet', '$pull', '$set'], key));
  var opt = opts[key];
  var fields = _.keys(opt);
  console.assert(fields.length === 1);
  var field = fields[0];

  _.each(vals, function(val) {
    switch (key) {
    case '$addToSet':
      val[field] = _.union(val[field], [opt[field]]);
      break;
    case '$pull':
      val[field] = _.without(val[field], opt[field]);
      break;
    case '$set':
      val[field] = opt[field];
      break;
    }
  });

  process.nextTick(function() {
    that.emit('change');
    cb();
  });
};

MemCollection.prototype.normalize_ = function(q) {
  if (_.isObject(q)) {
    return q;
  }
  return {_id: q};
};

MemCollection.prototype.matches_ = function(v, q) {
  var keys = _.keys(q);
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    if (_.isArray(v[key]) && !_.isArray(q[key])) {
      if (!_.contains(v[key], q[key])) {
        return false;
      }
    } else {
      if (q[key] !== v[key]) {
        return false;
      }
    }
  }
  return true;
};
