module.exports = function(sql) {

    var module={};

    module.connection = function(socket) {

        console.log("new client");

        function emit(signal, data, info) {
            if (typeof data == 'string') {
                console.log("<- signal: "+signal+"("+data+")");
            } else {
                console.log("<- signal: "+signal);
            }
            if (info) console.log(info);
            socket.emit(signal, data);
        }

        function broadcast(signal, data) {
            console.log("<= signal: "+signal);
            socket.broadcast.emit(signal, data);
        }

        socket.on("message", function(msg) {
            console.log("-> signal: message");
            if (!msg || !msg.user || !msg.content) return emit("fail", "wrong message format");
            sql.query("select pubkey from user where name = ?", [msg.user],
                      function(err, res, flds) {
                          if (err || !res || !res.length) return emit("fail", "unknown sender");
                          sql.query("insert into message set ?", {user: msg.user, msg: msg.content},
                                    function(err, result) {
                                        if (err) {
                                            if (err.code=='ER_NET_PACKET_TOO_LARGE')
                                                return emit('fail', "message too large", err);
                                            else
                                                return emit("fail", "cannot store message", err);
                                        }
                                        sql.query("select * from message, user"+
                                                  " where message.id = ? and"+
                                                  " message.user = user.name",
                                                  [result.insertId],
                                                  function(err, res, flds) {
                                                      broadcast('message', res[0]);
                                                      emit('message', res[0]);
                                                  });
                                    });
                      });
        });

        socket.on("messages", function(msg) {
            console.log("-> signal: messages");
            sql.query("select * from message, user where message.user = user.name order by message.id", [],
                      function(err, res, flds) {
                          emit('messages', res);
                      });
        });

        socket.on("login", function(user) {
            if (!user.name || !user.pubkey) return emit("fail", "wrong login format");
            console.log("-> signal: login("+user.name+")");
            if (user.name=="safechat") return emit("fail", "user name safechat is reserved");
            sql.query("select name, pubkey from user where name = ?", [user.name],
                      function(err, res, flds) {
                          if (err) return emit('fail', "login failed (db access)", err);
                          if (!res || res.length==0) {
                              sql.query("insert into user (name, pubkey) values (?,?)",
                                        [user.name, user.pubkey], function(err, res, flds) {
                                            if (err) return emit('fail', "create user failed", err);
                                            broadcast("user", {
                                                name: user.name, exists: false, pubkey: user.pubkey
                                            });
                                            emit('login');
                                        });
                          } else {
                              if (res[0].pubkey==user.pubkey) return emit('login');
                              emit('fail', "login failed - wrong credentials");
                          }
                      });
        });

        socket.on("user", function(name) {
            console.log("-> signal: user("+name+")");
            var result = {name: name, exists: false, pubkey: null};
            sql.query("select pubkey from user where name = ?", [name], function(err, res, flds) {
                if (!err && res && res.length) {
                    result.exists = true;
                    result.pubkey = res[0].pubkey;
                }
                emit('user', result);
            });
        });
        
        socket.on("users", function(name) {
            console.log("-> signal: users");
            sql.query("select name, pubkey from user", [name], function(err, res, flds) {
                if (!err && res && res.length) emit('users', res);
            });
        });
        
    };
    
    return module;
};
