import 'newrelic'
import http from 'http'
import express from 'express'
import winston from 'winston'
import expressWinston from 'express-winston'
import cors from 'cors'
import compression from 'compression'
import helmet from 'helmet'
import hpp from 'hpp'
import throng from 'throng'
import Raven from 'raven'
import dotenv from 'dotenv'
import path from 'path'

dotenv.config({ path: path.resolve(__dirname, '..', '.env') })

const DefaultServerConfig = {
  nodeEnv: process.env.NODE_ENV,
  port: process.env.PORT,
  timeout: 28000,
  schemaName: process.env.SCHEMA_NAME,
  databaseUrl: process.env.DATABASE_URL,
  sentryDns: process.env.SENTRY_DSN,
}

const createServer = (config) => {
  const PROD = config.nodeEnv === 'production'
  const app = express()

  if (PROD) {
    Raven.config(config.sentryDns).install()
    app.use(Raven.requestHandler())
  }

  app.use(expressWinston.logger({
    transports: [
      new winston.transports.Console({ colorize: true }),
    ],
    msg: 'HTTP {{req.method}} {{req.url}}',
    expressFormat: true,
    colorize: true,
  }))
  app.use(cors())
  app.use(helmet())
  app.use(hpp())
  app.use(compression())

  app.use(express.static(path.resolve(__dirname, '..', 'dist')))

  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, '..', 'dist', 'index.html'))
  })

  app.use(expressWinston.errorLogger({
    transports: [
      new winston.transports.Console({ colorize: true }),
    ],
  }))

  if (PROD) { 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
  if (config.timeout) {
    server.setTimeout(config.timeout, (socket) => {
      const message = `Timeout of ${config.timeout}ms exceeded`

      socket.end([
        'HTTP/1.1 503 Service Unavailable',
        `Date: ${(new Date).toGMTString()}`,  // eslint-disable-line
        'Content-Type: text/plain',
        `Content-Length: ${message.length}`,
        'Connection: close',
        '',
        message,
      ].join('\r\n'))
    })
  }

  return server
}

const startServer = (serverConfig) => {
  const config = { ...DefaultServerConfig, ...serverConfig }

  const server = createServer(config)
  server.listen(config.port, (err) => {
    if (err) winston.log(err)
    winston.info(`server ${config.id} listening on port ${config.port}`)
  })
}

if (require.main === module) {
  throng({
    start: id => startServer({ id }),
    workers: process.env.WEB_CONCURRENCY || 1,
    lifetime: Infinity,
  })
}

export default createServer

@@ -357,16 +357,42 @@
 m 'path'
+%0Aimport aws from 'aws-sdk'
 %0A%0Adotenv
@@ -673,16 +673,81 @@
 RY_DSN,%0A
+  s3BucketName: process.env.AWS_BUCKET %7C%7C 'vivo-em-nos-staging',%0A
 %7D%0A%0Aconst
@@ -1237,24 +1237,24 @@
 ression())%0A%0A
-
   app.use(ex
@@ -1303,24 +1303,706 @@
  'dist')))%0A%0A
+  app.get('/sign-s3', (req, res) =%3E %7B%0A    const s3 = new aws.S3()%0A    const fileName = req.query%5B'file-name'%5D%0A    const fileType = req.query%5B'file-type'%5D%0A    const s3Params = %7B%0A      Bucket: config.s3BucketName,%0A      Key: %60uploads/$%7BfileName%7D%60,%0A      Expires: 60,%0A      ContentType: fileType,%0A      ACL: 'public-read',%0A    %7D%0A%0A    s3.getSignedUrl('putObject', s3Params, (err, data) =%3E %7B%0A      if (err) %7B%0A        winston.log(err)%0A        return res.end()%0A      %7D%0A      const returnData = %7B%0A        signedRequest: data,%0A        url: %60https://$%7Bconfig.s3BucketName%7D.s3.amazonaws.com/$%7BfileName%7D%60,%0A      %7D%0A      res.write(JSON.stringify(returnData))%0A      return res.end()%0A    %7D)%0A  %7D)%0A%0A
   app.get('*

Add base endpoint to s3 signed url