mocha.setup('bdd');
window.assert = chai.assert;
window.PROTO_ROOT = '../protos';

(function() {
  var OriginalReporter = mocha._reporter;

  var SauceReporter = function(runner) {
    var failedTests = [];

    runner.on('end', function() {
      window.mochaResults = runner.stats;
      window.mochaResults.reports = failedTests;
    });

    runner.on('fail', function(test, err) {
      var flattenTitles = function(test) {
        var titles = [];
        while (test.parent.title) {
          titles.push(test.parent.title);
          test = test.parent;
        }
        return titles.reverse();
      };
      failedTests.push({
        name: test.title,
        result: false,
        message: err.message,
        stack: err.stack,
        titles: flattenTitles(test),
      });
    });

    new OriginalReporter(runner);
  };

  SauceReporter.prototype = OriginalReporter.prototype;

  mocha.reporter(SauceReporter);
})();

// Override the database id.
window.Whisper = window.Whisper || {};
window.Whisper.Database = window.Whisper.Database || {};
Whisper.Database.id = 'test';

/*
 * global helpers for tests
 */
function assertEqualArrayBuffers(ab1, ab2) {
  assert.deepEqual(new Uint8Array(ab1), new Uint8Array(ab2));
}

function hexToArrayBuffer(str) {
  var ret = new ArrayBuffer(str.length / 2);
  var array = new Uint8Array(ret);
  for (var i = 0; i < str.length / 2; i++) {
    array[i] = parseInt(str.substr(i * 2, 2), 16);
  }
  return ret;
}

function deleteDatabase() {
  return new Promise((resolve, reject) => {
    var idbReq = indexedDB.deleteDatabase('test');
    idbReq.onsuccess = resolve;
    idbReq.error = reject;
  });
}

/* Delete the database before running any tests */
before(async () => {
  await deleteDatabase();
  await window.Signal.Data.removeAll();

  await Signal.Migrations.Migrations0DatabaseWithAttachmentData.run({
    Backbone,
    databaseName: Whisper.Database.id,
    logger: window.log,
  });
});

async function clearDatabase() {
  const db = await Whisper.Database.open();
  await Whisper.Database.clear();
  await window.Signal.Data.removeAll();
}
