// 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 = Channel;

var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var inherits = require('inherits');
var path = require('path');
var url = require('url');

var access = require('vanadium/src/security/access');
var naming = require('vanadium').naming;
var noop = require('./noop');
var ServiceVdl = require('./v.io/x/chat/vdl');
var util = require('./util');

// Default channel name. Override by setting "channel" query param in url.
var DEFAULT_CHANNNEL = 'users/vanadium.bot@gmail.com/apps/chat/public';

// Member is a member of the channel.
function Member(blessings, path) {
  // The member's blessings.
  this.blessings = blessings;
  // The name of the member.
  this.name = util.firstShortName(blessings);
  // The path at which the member is mounted in the mounttable.
  this.path = path;
}

// memberNames takes an array of members and returns a sorted list of this
// names.
function memberNames(members) {
  return _.map(members, function(member) {
    return member.name;
  }).sort();
}

// Channel encapsulates the logic for a client of the Vanadium Chat.  It
// inherits from EventEmitter and emits 'members', 'message', and 'ready'
// events.
function Channel(rt) {
  EventEmitter.call(this);

  var u = url.parse(window.location.href, true);
  this.channelName_ = u.query.channel || DEFAULT_CHANNNEL;

  this.accountName_ = rt.accountName;
  this.namespace_ = rt.namespace();
  this.context_ = rt.getContext();
  this.client_ = rt.newClient();
  this.server_ = rt.newServer();

  this.globbing_ = false;
  this.ready_ = false;
  this.members_ = [];
  this.intervalID_ = null;
}

inherits(Channel, EventEmitter);

// join creates a Vanadium server and mounts it in the mounttable under a
// random "locked" name.
Channel.prototype.join = function(cb) {
  cb = cb || noop;
  var that = this;

  // Create our service implementation, which defines a single method:
  // "SendMessage".  We inherit from ServiceVdl.Chat which causes our defined
  // VDL types to be used when serializing values on the wire.  This is
  // necessary for the web client to be able to communicate with the shell
  // client.
  var Service = function() {
    ServiceVdl.Chat.call(this);
  };
  inherits(Service, ServiceVdl.Chat);

  // The implementation of sendMessage emits the message with the sender's
  // name and timestamp.
  Service.prototype.sendMessage = function(ctx, serverCall, text) {
    var secCall = serverCall.securityCall;
    that.emit('message', {
      sender: util.firstShortName(secCall.remoteBlessingStrings),
      text: text,
      timestamp: new Date()
    });
  };

  // allowEveryoneAuthorizer allows RPCs from all clients.
  var options = {authorizer: access.allowEveryoneAuthorizer()};

  // Get a locked name to mount under.
  this.getLockedName_(function(err, name) {
    if (err) {
      return cb(err);
    }

    that.mountedName_ = name;

    // Serve the chat service under the locked name.
    // Note, serve() performs the mount() for us.
    that.server_.serve(name, new Service(), options, function(err) {
      if (err) return cb(err);
      that.updateMembers_();
      that.intervalID_ = setInterval(that.updateMembers_.bind(that), 2000);
      return cb();
    });
  });
};

// getLockedName picks a random name and attempts to "lock" it by setting
// restrictive permissions.  It tries repeatedly until it picks a name that is
// not locked by another client.
Channel.prototype.getLockedName_ = function(cb) {
  // openACL gives everybody permission.
  var openACL = new access.AccessList({
    'in': ['...']
  });

  // myACL only gives my blessings and decendants permission.
  var myACL = new access.AccessList({
    'in': [this.accountName_]
  });

  // Create a tagged acl map with the desired permissions.
  var tam = new access.Permissions(new Map([
    // Give everybody the ability to read and resolve the name.
    ['Read', openACL],
    ['Resolve', openACL],
    // All other permissions are only for us.
    ['Admin', myACL],
    ['Create', myACL],
    ['Mount', myACL]
  ]));

  var that = this;

  // Repeatedly pick random names and try to setPermissions on them until we get
  // one that has not already been locked.
  var maxRetries = 25;
  function attemptToGetName(tries) {
    if (tries >= maxRetries) {
      return cb(new Error('Tried ' + maxRetries + ' to get an unlocked name ' +
            'but did not succeed.'));
    }

    // Choose a random name under the channel name.
    var name = path.join(that.channelName_, util.randomHex(32));
    var ctx = that.context_.withTimeout(5000);
    that.namespace_.setPermissions(ctx, name, tam, '', function(err) {
      ctx.done();
      if (err) {
        // Try again.
        return attemptToGetName(tries + 1);
      }
      return cb(null, name);
    });
  }

  attemptToGetName(0);
};

// leave stops the chat server, and deletes our name from the mounttable.
Channel.prototype.leave = function(cb) {
  cb = cb || noop;

  // Stop updating member names.
  if (this.intervalID_) {
    clearInterval(this.intervalID_);
    this.intervalID_ = null;
  }

  // Delete our name from the mounttable.
  if (this.mountedName_) {
    this.namespace_.delete(this.context_, this.mountedName_, true, noop);
  }

  // Stop the server.
  this.server_.stop(cb);
};

// sendMessageTo sends a message to a particular member.
Channel.prototype.sendMessageTo = function(member, messageText, cb) {
  cb = cb || noop;

  // The allowedServersPolicy options require that the server matches the
  // blessings we got when we globbed it.
  var callOpts = this.client_.callOption({
    allowedServersPolicy: member.blessings
  });

  var ctx = this.context_.withTimeout(5000);

  // Bind to the member's chat server.
  this.client_.bindTo(ctx, member.path, function(err, s) {
    if (err) {
      ctx.done();
      return cb(err);
    }

    // Invoke sendMessage on the member's chat server with messageText.
    s.sendMessage(ctx, messageText, callOpts, function(err) {
      if (err) {
        return cb(err);
      }
      ctx.done();
      return cb(null);
    });
  });
};

// broadcastMessage sends a message to all members in the channel.
Channel.prototype.broadcastMessage = function(messageText, cb) {
  cb = cb || noop;
  var that = this;

  // Schedule all messages to be sent, then return immediately.
  _.forEach(this.members_, function(member) {
    process.nextTick(function() {
      that.sendMessageTo(member, messageText);
    });
  });
  return cb(null);
};

// updateMembers_ globs the mounttable and constructs member objects for each
// server in the glob results.  Channel will emit 'members' event if the
// members have changed since the last glob.
Channel.prototype.updateMembers_ = function() {
  var that = this;

  // If we are already globbing, then do nothing.
  if (this.globbing_) {
    return;
  }
  this.globbing_ = true;

  // We glob on the channel name to find all the members in our channel.  The
  // glob will return a stream of mount entries corresponding to the paths where
  // channel members are mounted.  Then, we get the remote blessings from each
  // member, and use those as the member names.

  var ctx = this.context_.withTimeout(5000);
  var pattern = path.join(this.channelName_, '*');

  // Start the glob rpc.  This returns a promise with a "stream" property.
  // Mount entries are emitted on the stream.
  var globRpc = this.namespace_.glob(ctx, pattern);
  var globStream = globRpc.stream;
  globRpc.catch(function(err) {
    console.error(err);
  });

  var newMembers = [];

  // Each time we get a mount entry, we construct a new Member object.
  globStream.on('data', function(mountEntry) {
    if (!mountEntry.servers || mountEntry.servers.length === 0) {
      // No servers mounted at that name, only a lonely ACL.  Safe to ignore.
      return;
    }

    // TODO(ashankar,nlacasse): Check with p@ and figure out if
    // mountEntry.servers[0].server can have a "suffix" after the address.
    // (e.g., @4@...@@/foo/bar).
    // This won't be the case for the chat application, but can be in general?
    var addr = mountEntry.servers[0].server;
    var blessings = naming.blessingNamesFromAddress(addr);
    var path = mountEntry.name;

    newMembers.push(new Member(blessings, path));
  });

  globStream.on('end', done);

  function done(err) {
    that.globbing_ = false;
    if (err) {
      console.error(err);
    }

    if (newMembers.length === 0) {
      // No glob results, not even us!  Don't emit anything yet.
      return;
    }

    // Get the member names for the old and new members and if they differ
    // emit a "members" event which the UI will use to update the members
    // list.
    var oldMemberNames = memberNames(that.members_);
    that.members_ = newMembers;
    var newMemberNames = memberNames(that.members_);
    if (!_.isEqual(oldMemberNames, newMemberNames)) {
      that.emit('members', newMemberNames);
    }

    if (!that.ready_) {
      that.ready_ = true;
      that.emit('ready');
    }
  }
};
