text: 'use strict';
  
  var io = require('socket.io');
  var cookieParser = require('cookie-parser');
  var config = require('./config');
  var common = require('./common');
  var UserSocket = require('./utils/user-socket');
  var expressParser = cookieParser(config.session_secret);
  
  /*
   * websockets.init()
   *
   * Initialize the Socket.io server.
   */
  // sio: socketio server. ex: io.listen(server)
  function UserSockets(sio, sessionStore) {
    this.sio = sio;
    this.sockets = {};
    this.sessionStore = sessionStore;
    //sio.enable('browser client minification');  // send minified client
    //sio.enable('browser client etag');          // apply etag caching logic based on version number
    //sio.enable('browser client gzip');
    //sio.set('log level', 1);
    //sio.set('authorization', authorize.bind(this, sessionStore))
    sio.use(authorize.bind(this, sessionStore));
    sio.sockets.on('connection', this.connected.bind(this));
  }
  
  module.exports = UserSockets;
  
  UserSockets.prototype = {
    addSocket: function (uid, socket) {
      if (!this.sockets[uid]) {
        this.sockets[uid] = new UserSocket(uid);
      }
      this.sockets[uid].add(socket);
    },
    // -> true if the socket was found and removed. false if it wasn't found
    removeSocket: function (uid, socket) {
      var socks = this.sockets[uid];
      if (!socks) return false;
      return socks.remove(socket);
    },
    // socket callback. Adds a new socket
    connected: function (socket) {
      var session = socket.handshake.session;
      if (session && session.passport) {
        this.addSocket(session.passport.user, socket);
      } else {
        console.debug('Websocket connection does not have authorization - nothing to do.');
      }
    },
    // send a message to a number of users
    // send([uid, uid, ...], arguments)
    send: function (users, args) {
      for (var i = 0; i < users.length; i++) {
        if (!this.sockets[users[i]]) continue;
        this.sockets[users[i]].emit(args);
      }
    },
    // send a message to a number of users running callback to get args
    // send([uid, uid, ...], callback)
    sendEach: function (users, fn) {
      for (var i = 0; i < users.length; i++) {
        if (!this.sockets[users[i]] || !this.sockets[users[i]].user) continue;
        this.sockets[users[i]].emit(fn(this.sockets[users[i]].user));
      }
    },
    // send a public message - to all /but/ the specified users
    sendPublic: function (users, args) {
      for (var id in this.sockets) {
        if (users.indexOf(id) !== -1) continue;
        this.sockets[id].emit(args);
      }
    }
  };
  
  function authorize(sessionStore, data, next) {
    if (data.handshake.headers.cookie) {
      var req = data.handshake;
      expressParser(req, {}, function () {
        var sessionID = req.signedCookies['connect.sid'];
        sessionStore.get(sessionID, function (err, session) {
          if (err || !session) {
            next(new Error('not authorized'));
          } else {
            req.session = session;
            next();
          }
        });
      });
    } else {
      return next(new Error('not authorized'));
    }
  }
  
  module.exports.init = function (server, sessionStore) {
    return common.ws = new UserSockets(io.listen(server), sessionStore);
  };
  