'use strict';

var fs = require('fs');

function loadListeners(eventName) {
  var listeners = [];
  fs.readdirSync(__dirname + '/listeners/' + eventName + '/').forEach(function(file) {
    if (/^[^\.].*.js$/.test(file)) {
      var path = './listeners/' + eventName + '/' + file;
      listeners.push(require(path));
    }
  });
  return listeners;
}

var dbFile = process.env.HOME + '/.sectery.json';

function getDb() {
  if (fs.existsSync(dbFile)) {
    return JSON.parse(fs.readFileSync(dbFile));
  } else {
    return {};
  }
}

function saveDb(db) {
  fs.writeFileSync(dbFile, JSON.stringify(db, null, 2));
}

function sectery(client) {

  var db = getDb();
  db.cron = [];

  var replyQueue = [];

  var replyInterval = setInterval(function () {
    var reply = replyQueue.shift();
    if (reply) {
      if (reply.callback) {
        reply.callback(client.say.bind(client));
      } else if (reply.to && reply.message) {
        client.say(reply.to, reply.message);
      }
    }
  }, 2000);

  function reply(replies) {
    if (replies) {
      replies.forEach(function (reply) {
        replyQueue.push(reply);
      });
    }
    saveDb(db);
  }

  client.addListener('join', function (channel, nick, message) {
    function run(joinListener) {
      reply(joinListener(db, channel, nick, message));
    }
    loadListeners('join').forEach(run);
  });

  client.addListener('part', function(channel, nick, reason, message) {
    function run(partListener) {
      reply(partListener(db, channel, nick, reason, message));
    }
    loadListeners('part').forEach(run);
  });

  client.addListener('names', function(channel, names) {
    function run(namesListener) {
      reply(namesListener(db, channel, names));
    }
    loadListeners('names').forEach(run);
  });

  var messageCallback = function(from, to, message) {
    function run(messageListener) {
      try {
        reply(messageListener(db, from, to, message,messageCallback));
      } catch (e) {
        console.log('running message listener', e);
      }
    }
    loadListeners('message').forEach(run);
  };

  client.addListener('message', messageCallback); 

  client.addListener('pm', function (from, message) {
    function run(pmListener) {
      reply(pmListener(db, from, message));
    }
    loadListeners('pm').forEach(run);
  });

  return replyInterval;
}

module.exports = sectery;

@@ -701,42 +701,76 @@
 %5B%5D;%0A
-%0A
   
-var replyInterval = setInterval
+function reply(replies) %7B%0A    if (replies) %7B%0A      replies.forEach
 (fun
@@ -776,24 +776,29 @@
 nction (
+reply
 ) %7B%0A    
 var repl
@@ -793,19 +793,11 @@
     
-var reply =
+   
  rep
@@ -808,257 +808,545 @@
 eue.
-shift();%0A    if (reply) %7B%0A      if (reply.callback) %7B%0A        reply.callback(client.say.bind(client));%0A      %7D else if (reply.to && reply.message) %7B%0A        client.say(reply.to, reply.message);%0A      %7D%0A    %7D%0A  %7D, 2000);%0A%0A  function
+push(reply);%0A      %7D);%0A    %7D%0A    saveDb(db);%0A  %7D%0A%0A  var replyTimes = %5B%5D;%0A  function floodLimited() %7B%0A    var now = (new Date().getTime());%0A    var newReplyTimes = %5B%5D;%0A    for (var i = 0; i %3C replyTimes.length; i++) %7B%0A      var replyTime = replyTimes%5Bi%5D;%0A      if (now - replyTime %3C 10 * 1000) %7B%0A        newReplyTimes.push(replyTime);%0A      %7D%0A    %7D%0A    replyTimes = newReplyTimes;%0A    return (replyTimes.length %3E= 5);%0A  %7D%0A%0A  var replyInterval = setInterval(function () %7B%0A    if (!floodLimited()) %7B%0A      var
  reply
-(
+ = 
 repl
-ies) %7B%0A
+yQueue.shift();%0A  
     
@@ -1345,35 +1345,33 @@
 ;%0A      if (repl
-ies
+y
 ) %7B%0A      replie
@@ -1368,39 +1368,77 @@
     
+ 
+ 
 repl
-ies.forEach(function (reply
+yTimes.push((new Date()).getTime());%0A        if (reply.callback
 ) %7B%0A
@@ -1449,42 +1449,158 @@
     
+  
 reply
-Queue.push(reply
+.callback(client.say.bind(client));%0A        %7D else if (reply.to && reply.message) %7B%0A          client.say(reply.to, reply.message
 );%0A
+  
       %7D
-);%0A
+%0A  
     
@@ -1601,39 +1601,36 @@
       %7D%0A    
-saveDb(db);%0A  %7D
+%7D%0A  %7D, 250);
 %0A%0A  client.a

Allow message bursts of up to five per ten seconds