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

require('es6-shim');

var vanadium = require('vanadium');

var defineClass = require('./util/define-class');
var naming = require('./naming');

var SyncgroupManager = defineClass({
  publics: {
    createSyncGroup: function(name, prefixes) {
      var self = this;

      var sg = this.syncbaseWrapper.syncGroup(self.sgAdmin, name);

      var mgmt = vanadium.naming.join(this.mountNames.app, 'sgmt');
      var spec = sg.buildSpec(prefixes, [mgmt]);

      /* TODO(rosswang): Right now, duplicate Syncbase creates on
       * different Syncbase instances results in siloed SyncGroups.
       * Revisit this logic once it merges properly. */
      return sg.joinOrCreate(spec).then(function() {
        // TODO(rosswang): this is a hack to make the SyncGroup joinable
        return self.vanadiumWrapper.setPermissions(mgmt, new Map([
          ['Admin', {in: ['...']}],
          ['Read', {in: ['...']}],
          ['Resolve', {in: ['...']}]
        ]));
      }).then(function() {
        return sg;
      });
    },

    destroySyncGroup: function(name) {
      return this.syncbaseWrapper.syncGroup(this.sgAdmin, name).destroy();
    },

    joinSyncGroup: function(owner, name) {
      var sg = this.syncbaseWrapper.syncGroup(
        vanadium.naming.join(naming.appMount(owner), 'sgadmin'), name);
      return sg.join();
    },

    addCollaborator: function(sgName, username) {
      
    }
  },

  privates: {
    advertise: function() {
      var basicPerms = new Map([
        ['Admin', {in: [this.identity.account]}],
        ['Read', {in: ['...']}],
        ['Resolve', {in: ['...']}]
      ]);

      return Promise.all([
        /* TODO(rosswang): this is a very short term hack just because user
         * mount names on ns.dev.v.io don't yet default to Resolve in [...].
         */
        this.vanadiumWrapper.setPermissions(this.mountNames.user, basicPerms),
        this.vanadiumWrapper.setPermissions(this.mountNames.app, basicPerms)
      ]);
    }
  },

  constants: [ 'sgAdmin', 'syncbaseWrapper' ],

  events: {
    onError: 'memory'
  },

  init: function(identity, vanadiumWrapper, syncbaseWrapper, mountNames) {
    this.identity = identity;
    this.vanadiumWrapper = vanadiumWrapper;
    this.syncbaseWrapper = syncbaseWrapper;
    this.mountNames = mountNames;

    this.sgAdmin = vanadium.naming.join(mountNames.app, 'sgadmin');

    this.advertise().catch(this.onError);
  }
});

module.exports = SyncgroupManager;
