const http = require('http');
const express = require('express');
const morgan = require('morgan');
const raven = require('raven');

const staticAssets = require('./middleware/staticAssets');
const createRouter = require('./createRouter');

morgan.token('fwd', req => {
  const fwd = req.get('x-forwarded-for');
  return fwd ? fwd.replace(/\s/g, '') : '-';
});

if (process.env.SENTRY_DSN) {
  raven
    .config(process.env.SENTRY_DSN, {
      release: process.env.HEROKU_RELEASE_VERSION,
      autoBreadcrumbs: true
    })
    .install();
}

// function errorHandler(err, req, res, next) {
//   console.error(err.stack);

//   res
//     .status(500)
//     .type("text")
//     .send("Internal Server Error");

//   next(err);
// }

function createServer(publicDir, statsFile) {
  const app = express();

  app.disable('x-powered-by');

  if (process.env.SENTRY_DSN) {
    app.use(raven.requestHandler());
  }

  if (process.env.NODE_ENV !== 'test') {
    app.use(
      morgan(
        // Modified version of Heroku's log format
        // https://devcenter.heroku.com/articles/http-routing#heroku-router-log-format
        'method=:method path=":url" host=:req[host] request_id=:req[x-request-id] cf_ray=:req[cf-ray] fwd=:fwd status=:status bytes=:res[content-length]'
      )
    );
  }

  // app.use(errorHandler);

  if (publicDir) {
    app.use(express.static(publicDir, { maxAge: '365d' }));
  }

  if (statsFile) {
    app.use(staticAssets(statsFile));
  }

  app.use(createRouter());

  if (process.env.SENTRY_DSN) {
    app.use(raven.errorHandler());
  }

  const server = http.createServer(app);

  // Heroku dynos automatically timeout after 30s. Set our
  // own timeout here to force sockets to close before that.
  // https://devcenter.heroku.com/articles/request-timeout
  server.setTimeout(25000, socket => {
    const message = `Timeout of 25 seconds exceeded`;

    socket.end(
      [
        'HTTP/1.1 503 Service Unavailable',
        'Date: ' + new Date().toGMTString(),
        'Content-Length: ' + Buffer.byteLength(message),
        'Content-Type: text/plain',
        'Connection: close',
        '',
        message
      ].join('\r\n')
    );
  });

  return server;
}

module.exports = createServer;