const io = require('socket.io');
const cookieParser = require('cookie-parser');
const config = require('./config');
const common = require('./common');
const UserSocket = require('./utils/user-socket');
const 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) {
        const socks = this.sockets[uid];
        if (!socks)
            return false;
        return socks.remove(socket);
    },
    // socket callback. Adds a new socket
    connected: function (socket) {
        const 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 (let 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 (let 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 (const 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) {
        const req = data.handshake;
        expressParser(req, {}, function () {
            const 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));
};
//# sourceMappingURL=websockets.js.map