'use strict';

/**
 * @author Hung Phan
 *            _     _     _ _
 *           (_)   | |   | | |
 *  _ __ ___  _  __| | __| | | _____      ____ _ _ __ ___  ___
 * | '_ ` _ \| |/ _` |/ _` | |/ _ \ \ /\ / / _` | '__/ _ \/ __|
 * | | | | | | | (_| | (_| | |  __/\ V  V / (_| | | |  __/\__ \
 * |_| |_| |_|_|\__,_|\__,_|_|\___| \_/\_/ \__,_|_|  \___||___/
 */

import koa          from 'koa';
import path         from 'path';
import cors         from 'koa-cors';
import middlewares  from 'koa-middlewares';
import htmlMinifier from 'koa-html-minifier';
import {PUBLIC}     from 'config/path-helper';

const settings = {
  bodyParser: {
    // https://github.com/koajs/bodyparser
    enable: true,
    params: []
  },
  logger: {
    // https://github.com/koajs/logger
    enable: true,
    params: []
  },
  compress: {
    // https://github.com/koajs/compress
    enable: true,
    params: []
  },
  session: {
    // https://github.com/koajs/session
    enable: true
  },
  csrf: {
    // https://github.com/koajs/csrf
    // must also enable session to work correctly
    enable: true
  },
  conditional: {
    // https://github.com/koajs/conditional-get
    enable: false,
    params: []
  },
  etag: {
    // https://github.com/koajs/etag
    enable: false,
    params: []
  },
  cors: {
    // https://github.com/koajs/cors
    enable: false,
    params: []
  },
  favicon: {
    // https://github.com/koajs/favicon
    enable: true,
    params: [path.join(PUBLIC, 'favicon.ico')]
  },
  staticCache: {
    // https://github.com/koajs/static-cache
    enable: true,
    params: [PUBLIC, { gzip: true }]
  },
  htmlMinifier: {
    // https://github.com/kangax/html-minifier
    enable: true,
    params: [{
      collapseWhitespace: true,
      removeComments: true,
      preserveLineBreaks: process.env.NODE_ENV === 'development'
    }]
  }
};

function applyMiddlewares(app, middleware, options) {
  if (options.enable) {
    app.use(options.hasOwnProperty('params') ? middleware(...options.params) : middleware);
  }
}

export default function(app: koa) {
  applyMiddlewares(app, middlewares.bodyParser, settings.bodyParser);
  applyMiddlewares(app, middlewares.logger, settings.logger);
  applyMiddlewares(app, middlewares.compress, settings.compress);
  applyMiddlewares(app, middlewares.conditional, settings.conditional);
  applyMiddlewares(app, middlewares.etag, settings.etag);
  applyMiddlewares(app, middlewares.cors, settings.cors);
  applyMiddlewares(app, middlewares.favicon, settings.favicon);
  applyMiddlewares(app, middlewares.staticCache, settings.staticCache);
  applyMiddlewares(app, htmlMinifier, settings.htmlMinifier);

  // session and csrf
  if (settings.session.enable && settings.csrf.enable) {
    app.keys = ['read from env'];
    middlewares.csrf(app);

    applyMiddlewares(app, middlewares.cookieSession(app), settings.session);
    applyMiddlewares(app, middlewares.csrf.middleware, settings.csrf);
  }
}

@@ -617,287 +617,8 @@
 = %7B%0A
-  bodyParser: %7B%0A    // https://github.com/koajs/bodyparser%0A    enable: true,%0A    params: %5B%5D%0A  %7D,%0A  logger: %7B%0A    // https://github.com/koajs/logger%0A    enable: true,%0A    params: %5B%5D%0A  %7D,%0A  compress: %7B%0A    // https://github.com/koajs/compress%0A    enable: true,%0A    params: %5B%5D%0A  %7D,%0A
   se
@@ -803,24 +803,121 @@
 : true%0A  %7D,%0A
+  bodyParser: %7B%0A    // https://github.com/koajs/bodyparser%0A    enable: true,%0A    params: %5B%5D%0A  %7D,%0A
   conditiona
@@ -1655,16 +1655,198 @@
 %0A    %7D%5D%0A
+  %7D,%0A  compress: %7B%0A    // https://github.com/koajs/compress%0A    enable: true,%0A    params: %5B%5D%0A  %7D,%0A  logger: %7B%0A    // https://github.com/koajs/logger%0A    enable: true,%0A    params: %5B%5D%0A
   %7D%0A%7D;%0A%0A
@@ -2058,16 +2058,159 @@
  koa) %7B%0A
+  // session and csrf%0A  if (settings.session.enable && settings.csrf.enable) %7B%0A    app.keys = %5B'read from env'%5D;%0A    middlewares.csrf(app);%0A%0A  
   applyM
@@ -2237,26 +2237,34 @@
 lewares.
-bodyParser
+cookieSession(app)
 , settin
@@ -2270,21 +2270,20 @@
 ngs.
-bodyParser
+session
 );%0A
+  
   ap
@@ -2318,33 +2318,45 @@
 res.
-logger, settings.logger);
+csrf.middleware, settings.csrf);%0A  %7D%0A
 %0A  a
@@ -2388,24 +2388,26 @@
 lewares.
-compress
+bodyParser
 , settin
@@ -2409,24 +2409,26 @@
 ettings.
-compress
+bodyParser
 );%0A  app
@@ -2812,152 +2812,8 @@
 r);%0A
-%0A  // session and csrf%0A  if (settings.session.enable && settings.csrf.enable) %7B%0A    app.keys = %5B'read from env'%5D;%0A    middlewares.csrf(app);%0A%0A  
   ap
@@ -2846,32 +2846,22 @@
 wares.co
-okieSession(app)
+mpress
 , settin
@@ -2859,36 +2859,35 @@
 s, settings.
-session
+compress
 );%0A
-  
   applyMiddl
@@ -2906,39 +2906,30 @@
 middlewares.
-csrf.middleware
+logger
 , settings.c
@@ -2927,21 +2927,19 @@
 ettings.
-csrf);%0A  %7D
+logger);
 %0A%7D%0A

refactor middlewares