import {Request, Response} from 'koa'
import { Get, Controller, Req, Res} from '@gem-mine/routing-controllers'

const HEARTBEAT = 5000
const clients = {}
let clientId = 0

function createEventStream(heartbeat) {
  function everyClient(fn) {
    Object.keys(clients).forEach(function(id) {
      fn(clients[id])
    })
  }
  const interval = setInterval(function heartbeatTick() {
    everyClient(function(client) {
      client.write('data: \uD83D\uDC93\n\n')
    })
  }, heartbeat)
  return {
    handler: function(req, res) {
      const PassThrough = require('stream').PassThrough
      const stream = new PassThrough()
      res.body = stream
      res.write = stream.write.bind(stream)
      res.write('\n')

      var isHttp1 = !(parseInt(req.httpVersion) >= 2)
      if (isHttp1) {
        req.socket.setKeepAlive(true)
        res.set('Connection', 'keep-alive')
      }

      res.set('X-Accel-Buffering', 'no')
      res.set('Access-Control-Allow-Origin', '*')
      res.set('Cache-Control', 'no-cache, no-transform')
      res.set('Content-Type', 'text/event-stream;charset=utf-8')

      res.status = 200
      stream.on('error', () => {})
      let id = clientId++
      clients[id] = res
      stream.on('close', function() {
        clearInterval(interval)
        delete clients[id]
      })
    }
  }
}

@Controller('/heartbeat')
export default class {
  @Get('/')
  async get(@Req() request: Request, @Res() response: Response) {
    const eventStream = createEventStream(HEARTBEAT)
    eventStream.handler(request, response)
    return response
  }

  @Get('/count')
  async count() {
    return {
      data: {
        client: Object.keys(clients).length
      }
    }
  }
}
