var config = require('./config'),
    httpServer,
    express = require('express'),
    partials = require('express-partials'),
    authManager = require('./lib/authentication'),
    passport = authManager.passport,
    socketAuthenticator = require('./lib/socket-auth'),
    pullManager = require('./lib/pull-manager'),
    dbManager = require('./lib/db-manager'),
    gitManager = require('./lib/git-manager'),
    Pull = require('./models/pull'),
    Signature = require('./models/signature'),
    mainController = require('./controllers/main'),
    pullController = require('./controllers/pull')(pullManager),
    hooksController = require('./controllers/githubHooks');

var app = express();

httpServer = require('http').createServer(app)

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');


/**
 * Middleware
 */
app.use("/public", express.static(__dirname + '/public'));
app.use(partials());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: config.session.secret}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.logger());


/**
 * Routes
 */
authManager.setupRoutes(app);
app.get('/',         mainController.index);
app.get('/pull',     pullController.index);
app.get('/pull/add', pullController.add);
app.post('/hooks/main', hooksController.main);


/**
 * Accepts a promise that resolves to a pull, adds it to the view, updates the
 * DB to reflect any changes.
 */
function update(pullPromise) {
   pullPromise.done(function(pull) {
      dbManager.updatePull(pull).done(function() {
         if (pull.commitStatus) {
            dbManager.updateCommitStatus(pull.commitStatus);
         }

         // Delete all signatures related to this pull from the DB
         // before we rewrite them to avoid duplicates.
         dbManager.deleteSignatures(pull.data.number).done(function() {
            pull.signatures.sort(Signature.compare);
            dbManager.insertSignatures(pull.signatures);
         });

         pull.comments.forEach(function(comment) {
            dbManager.updateComment(comment);
         });
      });
   });
}

/**
 * Refreshes the specified pull.
 */
function refresh(number) {
   var githubPull = gitManager.getPull(number);

   githubPull.done(function(gPull) {
      var pullPromise = gitManager.parse(gPull);
      update(pullPromise);
   });
}

/**
 * Refreshes all open pulls.
 */
function refreshAll() {
   var githubPulls = gitManager.getAllPulls();

   githubPulls.done(function(gPulls) {
      gPulls.forEach(function(gPull) {
         var pull = gitManager.parse(gPull);
         update(pull);
      });
   });
}


// Called, to populate app, on startup.
refreshAll();

/*
@TODO: Update pulls which were open last time Pulldasher ran but are closed now.
dbManager.closeStalePulls();
*/


//====================================================
// Socket.IO

var io = require('socket.io').listen(httpServer);
io.set('log level', 2);
io.sockets.on('connection', function (socket) {
   socket.on('authenticate', function(token) {
      var user = socketAuthenticator.retrieveUser(token);
      if (user) {
         socket.emit('authenticated');
         pullManager.addSocket(socket);
         clearTimeout(autoDisconnect);
      } else {
         socket.disconnect();
      }
   });

   socket.on('refresh', function(number) {
      if (number) {
         refresh(number);
      } else {
         refreshAll();
      }
   });

   var autoDisconnect = setTimeout(function() {
      socket.disconnect();
   }, 10*1000);
});

httpServer.listen(config.port);

@@ -117,24 +117,58 @@
 partials'),%0A
+    Promise = require('promise'),%0A
     authMana
@@ -1543,16 +1543,69 @@
 mise) %7B%0A
+   return new Promise(function(resolve, reject) %7B%0A   
    pullP
@@ -1629,24 +1629,27 @@
 ion(pull) %7B%0A
+   
       dbMana
@@ -1679,32 +1679,66 @@
 ne(function() %7B%0A
+            var updates = %5B%5D;%0A%0A   
          if (pul
@@ -1751,24 +1751,59 @@
 itStatus) %7B%0A
+               updates.push(%0A      
             
@@ -1849,16 +1849,33 @@
 tStatus)
+%0A               )
 ;%0A      
@@ -1877,19 +1877,25 @@
         
-%7D%0A%0A
+   %7D%0A%0A   
         
@@ -1962,16 +1962,19 @@
         
+   
 // befor
@@ -2012,16 +2012,19 @@
 icates.%0A
+   
         
@@ -2095,24 +2095,27 @@
             
+   
 pull.signatu
@@ -2143,16 +2143,51 @@
 mpare);%0A
+               updates.push(%0A      
         
@@ -2233,18 +2233,38 @@
 natures)
-;
 %0A
+               );%0A   
         
@@ -2274,24 +2274,27 @@
 ;%0A%0A         
+ 
+  
 pull.comment
@@ -2339,39 +2339,201 @@
     
-dbManager.updateComment(comment
+   updates.push(%0A                  dbManager.updateComment(comment)%0A               );%0A            %7D);%0A%0A            Promise.all(updates).done(function() %7B%0A               resolve();%0A            %7D
 );%0A 

change `update` so it returns a promise