// 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.

module.exports = {
  appExists: appExists,
  databaseExists: databaseExists,
  tableExists: tableExists,

  setupApp: setupApp,
  setupDatabase: setupDatabase,
  setupService: setupService,
  setupSyncGroup: setupSyncGroup,
  setupTable: setupTable,

  assertScanRows: assertScanRows,
  testGetSetPermissions: testGetSetPermissions,
  uniqueName: uniqueName
};

var deepEqual = require('deep-equal');
var extend = require('xtend');
var streamToArray = require('stream-to-array');
var vanadium = require('vanadium');

var syncbase = require('../..');
var syncbaseSuffix = syncbase.syncbaseSuffix;

var SERVICE_NAME = require('./service-name');

// Helper function to generate unique names.
var nameCounter = Date.now();

function uniqueName(prefix) {
  prefix = prefix || 'name';
  return prefix + '_' + nameCounter++;
}

// Initializes Vanadium runtime.
function setupService(t, cb) {
  vanadium.init(function(err, rt) {
    if (err) {
      return cb(err);
    }

    function teardown(cb) {
      rt.close(function(err) {
        t.error(err, 'rt.close should not error.');
        cb(null);
      });
    }

    var service = syncbase.newService(SERVICE_NAME);

    return cb(null, {
      ctx: rt.getContext(),
      rt: rt,
      service: service,
      teardown: teardown
    });
  });
}

// Initializes Vanadium runtime and creates an App.
function setupApp(t, cb) {
  setupService(t, function(err, o) {
    if (err) {
      return cb(err);
    }

    var app = o.service.app(uniqueName('app'));

    app.create(o.ctx, {}, function(err) {
      if (err) {
        o.rt.close(t.error);
        return cb(err);
      }

      return cb(null, extend(o, {
        app: app
      }));
    });
  });
}

// Initializes Vanadium runtime and creates an App and a Database.
function setupDatabase(t, cb) {
  setupApp(t, function(err, o) {
    if (err) {
      return cb(err);
    }

    var db = o.app.noSqlDatabase(uniqueName('db'));

    db.create(o.ctx, {}, function(err) {
      if (err) {
        o.rt.close(t.error);
        return cb(err);
      }

      return cb(null, extend(o, {
        database: db
      }));
    });
  });
}

// Initializes Vanadium runtime and creats an App, Database and SyncGroup.
function setupSyncGroup(t, perms, prefixes, cb) {
  setupDatabase(t, function(err, o) {
    if (err) {
      return cb(err);
    }

    var sgName = uniqueName('syncgroup');
    var fullSgName = vanadium.naming.join(o.service.fullName,
                                          syncbaseSuffix,
                                          sgName);

    // TODO(nlacasse): Where does this magic number 8 come from? It's in
    // syncgroup_test.go.
    var myInfo = new syncbase.nosql.SyncGroupMemberInfo({
      syncPriority: 8
    });

    var spec = new syncbase.nosql.SyncGroupSpec({
      description: 'test syncgroup ' + fullSgName,
      perms: perms,
      prefixes: prefixes
    });

    var sg = o.database.syncGroup(fullSgName);
    sg.create(o.ctx, spec, myInfo, function(err) {
      if (err) {
        o.rt.close(t.error);
        return cb(err);
      }

      return cb(null, extend(o, {
        syncgroup: sg
      }));
    });
  });
}

// Initializes Vanadium runtime and creates an App, a Database and a Table.
function setupTable(t, cb) {
  setupDatabase(t, function(err, o) {
    if (err) {
      return cb(err);
    }
    var db = o.database;

    var tableName = uniqueName('table');
    db.createTable(o.ctx, tableName, {}, function(err) {
      if (err) {
        o.rt.close(t.error);
        return cb(err);
      }

      return cb(null, extend(o, {
        table: db.table(tableName)
      }));
    });
  });
}

// Assert that two permissions objects are equal.
function assertPermissionsEqual(t, got, want) {
  t.equal(got.size, want.size, 'Permissions size matches');
  want.forEach(function(value, key) {
    t.deepEqual(got.get(key), value, 'Permission value matches');
  });
}

// For any object that implements get/setPermissions, test that getting and
// setting permissions behaves as it should.
function testGetSetPermissions(t, ctx, obj, cb) {
  obj.getPermissions(ctx, function(err, perms, version) {
    if (err) {
      t.error('error getting permissions ' + err);
      return cb(err);
    }

    t.ok(perms, 'Has permissions');
    t.ok(version, 'Has a version');

    var newPerms = new Map([
      ['Read', {
        'in': ['...', 'canRead'],
        'notIn': ['cantRead']
      }],
      ['Write', {
        'in': ['...', 'canWrite'],
        'notIn': ['cantWrite']
      }],
      ['Admin', {
        'in': ['...', 'canAdmin'],
        'notIn': ['cantAdmin']
      }]
    ]);

    obj.setPermissions(ctx, newPerms, version, function(err) {
      if (err) {
        t.error('error setting permissions ' + err);
        return cb(err);
      }

      obj.getPermissions(ctx, function(err, gotPerms, gotVersion) {
        if (err) {
          t.error('error getting permissions ' + err);
          return cb(err);
        }

        t.ok(perms, 'Has permissions');
        t.ok(version, 'Has a version');

        t.notEqual(version, gotVersion, 'should have a new version');
        assertPermissionsEqual(t, gotPerms, newPerms);
        return cb(null);
      });
    });
  });
}

function appExists(ctx, service, name, cb) {
  service.listApps(ctx, function(err, names) {
    if (err) {
      return cb(err);
    }

    cb(null, names.indexOf(name) >= 0);
  });
}

function databaseExists(ctx, app, name, cb) {
  app.listDatabases(ctx, function(err, names) {
    if (err) {
      return cb(err);
    }

    cb(null, names.indexOf(name) >= 0);
  });
}

function tableExists(ctx, db, name, cb) {
  db.listTables(ctx, function(err, names) {
    if (err) {
      return cb(err);
    }

    cb(null, names.indexOf(name) >= 0);
  });
}

function compareRows(r1, r2) {
  if (r1.key > r2.key) {
    return 1;
  }
  if (r1.key < r2.key) {
    return -1;
  }
  if (r1.value > r2.value) {
    return 1;
  }
  if (r1.value < r2.value) {
    return -1;
  }
  return 0;
}

function assertScanRows(ctx, table, range, wantRows, cb) {
  var stream = table.scan(ctx, range, function(err) {
    if (err) {
      return cb(err);
    }
  });

  streamToArray(stream, function(err, rows) {
    if (err) {
      return cb(err);
    }

    rows = rows || [];

    rows.sort(compareRows);
    wantRows.sort(compareRows);

    if (!deepEqual(rows, wantRows)) {
      var error = new Error('Expected rows to be ' + JSON.stringify(wantRows) +
                        ' but got ' + JSON.stringify(rows));
      return cb(error);
    }

    cb(null);
  });
}
