const Koa = require('koa');
const serve = require('koa-static');
const socketRoute = require('koa-route');
const mount = require('koa-mount');
const bodyParser = require('koa-bodyparser');
const path = require('path');
const debounce = require('lodash.debounce');
const websockify = require('koa-websocket');
const favicon = require('koa-favicon');
const Router = require('./router');
const JukeBox = require('./jukebox');

const app = websockify(new Koa());
const jukebox = new JukeBox();

// provide application objects
app.context.jukebox = jukebox;

const router = new Router();
router.allBind(jukebox);

// use body parser
app.use(bodyParser());

if (!process.env.JUKEBOX_NO_WEB_UI) {
  // static files
  app.use(favicon(path.join(__dirname, '../assets/favicon.ico')));
  app.use(mount('/', serve(path.join(__dirname, '../assets/'))));
}

// define broadcast function to websocket
app.ws.broadcast = data => {
  app.ws.server.clients.forEach(client => {
    if (client.readyState === 1) {
      // websocket connection is open
      client.send(data);
    }
  });
};

jukebox.player.on(
  'updated-status',
  debounce(() => {
    const status = jukebox.player.fetchStatus();
    app.ws.broadcast(
      JSON.stringify({
        name: 'update-status',
        data: status
      })
    );

    jukebox.player.save();
  }, 200)
);

jukebox.history.on(
  'updated',
  debounce(() => {
    const historyData = jukebox.history.toJson();
    app.ws.broadcast(
      JSON.stringify({
        name: 'update-history',
        data: historyData
      })
    );

    // save history
    jukebox.history.save();
  }, 1000)
);

// websocket connection
app.ws.use(socketRoute.get('/socket', () => {}));
app.use(router.routes());
app.use(router.allowedMethods());

let port = 8888;
if (process.env.JUKEBOX_PORT) {
  port = process.env.JUKEBOX_PORT;
}

const server = app.listen(port);

module.exports = {
  app,
  server
};

@@ -338,24 +338,56 @@
 -favicon');%0A
+const Debug = require('debug');%0A
 const Router
@@ -459,129 +459,432 @@
 nst 
-app = websockify(new Koa());%0Aconst jukebox = new JukeBox();%0A%0A// provide application objects%0Aapp.context.jukebox = jukebox
+debug = %7B%0A  server: Debug('jukebox:server'),%0A  http: Debug('jukebox:server:http'),%0A  ws: Debug('jukebox:server:http')%0A%7D;%0A%0Aconst app = websockify(new Koa());%0Aconst jukebox = new JukeBox();%0A%0A// provide application objects%0Aapp.context.jukebox = jukebox;%0A%0A// logger%0Aapp.use(async (ctx, next) =%3E %7B%0A  const start = new Date();%0A  await next();%0A  const ms = new Date() - start;%0A  debug.http(%60$%7Bctx.method%7D $%7Bctx.url%7D - $%7Bms%7Dms%60);%0A%7D)
 ;%0A%0Ac
@@ -1245,16 +1245,125 @@
  =%3E %7B%0A  
+const message = JSON.stringify(data);%0A  debug.ws('broadcast %25s, size: %25d', data.name, message.length);%0A  %5B...
 app.ws.s
@@ -1379,16 +1379,21 @@
 ents
-.forEach
+%5D%0A    .filter
 (cli
@@ -1403,18 +1403,8 @@
  =%3E 
-%7B%0A    if (
 clie
@@ -1427,16 +1427,8 @@
 = 1)
- %7B%0A     
  // 
@@ -1456,16 +1456,41 @@
 is open%0A
+    .forEach(client =%3E %7B%0A
       cl
@@ -1503,21 +1503,20 @@
 end(
-data
+message
 );%0A  
-  %7D%0A
   %7D)
@@ -1653,34 +1653,10 @@
 ast(
+%7B
 %0A
-      JSON.stringify(%7B%0A  
     
@@ -1680,18 +1680,16 @@
 tatus',%0A
-  
       da
@@ -1699,33 +1699,25 @@
  status%0A    
-  %7D)%0A    
+%7D
 );%0A%0A    juke
@@ -1876,34 +1876,10 @@
 ast(
+%7B
 %0A
-      JSON.stringify(%7B%0A  
     
@@ -1904,18 +1904,16 @@
 story',%0A
-  
       da
@@ -1936,17 +1936,9 @@
     
-  %7D)%0A    
+%7D
 );%0A%0A
@@ -2254,16 +2254,205 @@
 n(port);
+%0Aserver.on('listening', () =%3E %7B%0A  const addr = server.address();%0A  const bind = typeof addr === 'string' ? %60pipe $%7Baddr%7D%60 : %60port $%7Baddr.port%7D%60;%0A  debug.server('Listening on %25s', bind);%0A%7D);
 %0A%0Amodule

add debug in app.js