'use strict';

var commonUtils = require('deltadb-common-utils');

var Utils = function () {};

// Long timeout needed for saucelabs tests
Utils.prototype.TIMEOUT = 20000;

// TODO: move to deltadb-server
Utils.prototype.changesShouldEql = function (expected, actual) {
  this.sortChanges(actual);
  this.sortChanges(expected);
  actual.forEach(function (change, i) {
    if (expected[i] && change.re) {
      expected[i].re = change.re;
    }

    if (expected[i] && change.up) {
      expected[i].up = change.up;
    }

    if (expected[i] && change.id) {
      expected[i].id = change.id;
    }
  });
  this.eqls(expected, actual);
};

// TODO: move to deltadb-server
Utils.prototype.sortChanges = function (changes) {
  var attrs = ['col', 'name', 'up', 'seq', 'val'];
  return commonUtils.sort(changes, attrs);
};

// TODO: move to deltadb-server
Utils.prototype.eqls = function (expected, actual) {
  // Convert to milliseconds so that errors report specific problems--expect doesn't compare
  // milliseconds by default
  this.toTime(actual).should.eql(this.toTime(expected));
};

// TODO: move to deltadb-server
Utils.prototype.toTime = function (rows) {
  rows.forEach(function (cells) {
    for (var j in cells) {
      if (cells[j] instanceof Date) {
        cells[j] = cells[j].getTime();
      }
    }
  });
  return rows;
};

Utils.prototype.sleep = function (sleepMs) {
  // Ensure a different timestamp will be generated after this function resolves.
  // Occasionally, using timeout(1) will not guarantee a different timestamp, e.g.:
  //   1. (new Date()).getTime()
  //   2. timeout(1)
  //   3. (new Date()).getTime()
  // It is not clear as to what causes this but the solution is to sleep longer. This function is
  // also used to delay between DB writes to create predictable patterns. In this case it may be
  // that the DB adapter processes queries out of sequence.
  return commonUtils.timeout(sleepMs ? sleepMs : 10);
};

Utils.prototype.allShouldEql = function (collection, expected) {
  // Index data as order is guaranteed

  var allDocs = {};

  var allExpDocs = {};
  expected.forEach(function (exp) {
    allExpDocs[exp.$id] = exp;
  });

  return collection.all(function (item) {
    allDocs[item.id()] = item.get();
  }).then(function () {
    allDocs.should.eql(allExpDocs);
  });
};

module.exports = new Utils();

@@ -170,1175 +170,8 @@
 0;%0A%0A
-// TODO: move to deltadb-server%0AUtils.prototype.changesShouldEql = function (expected, actual) %7B%0A  this.sortChanges(actual);%0A  this.sortChanges(expected);%0A  actual.forEach(function (change, i) %7B%0A    if (expected%5Bi%5D && change.re) %7B%0A      expected%5Bi%5D.re = change.re;%0A    %7D%0A%0A    if (expected%5Bi%5D && change.up) %7B%0A      expected%5Bi%5D.up = change.up;%0A    %7D%0A%0A    if (expected%5Bi%5D && change.id) %7B%0A      expected%5Bi%5D.id = change.id;%0A    %7D%0A  %7D);%0A  this.eqls(expected, actual);%0A%7D;%0A%0A// TODO: move to deltadb-server%0AUtils.prototype.sortChanges = function (changes) %7B%0A  var attrs = %5B'col', 'name', 'up', 'seq', 'val'%5D;%0A  return commonUtils.sort(changes, attrs);%0A%7D;%0A%0A// TODO: move to deltadb-server%0AUtils.prototype.eqls = function (expected, actual) %7B%0A  // Convert to milliseconds so that errors report specific problems--expect doesn't compare%0A  // milliseconds by default%0A  this.toTime(actual).should.eql(this.toTime(expected));%0A%7D;%0A%0A// TODO: move to deltadb-server%0AUtils.prototype.toTime = function (rows) %7B%0A  rows.forEach(function (cells) %7B%0A    for (var j in cells) %7B%0A      if (cells%5Bj%5D instanceof Date) %7B%0A        cells%5Bj%5D = cells%5Bj%5D.getTime();%0A      %7D%0A    %7D%0A  %7D);%0A  return rows;%0A%7D;%0A%0A
 Util

move some fns to deltadb-server