const describe = require('mocha').describe
const it = require('mocha').it
const beforeEach = require('mocha').beforeEach
const afterEach = require('mocha').afterEach
const assert = require('chai').assert
const sinon = require('sinon')

const database = require('../lib/storage/database')
const encryption = require('../lib/storage/encryption')
const route = require('../lib/http/route')
const response = require('../lib/http/response')
const receiveHandler = require('../handlers/receive/handler')
const receiveRequest = require('../handlers/receive/request')
const encryptHandler = require('../handlers/encrypt/handler')

const eventReceiveSuccess = require('../events/receive-success.json')
const eventReceiveSuccessJson = require('../events/receive-success-json.json')
const eventReceiveBadEmail = require('../events/receive-bad-email.json')
const eventReceiveNoEmail = require('../events/receive-no-email.json')
const eventReceiveHoneypot = require('../events/receive-honeypot.json')
const eventEncryptSuccess = require('../events/encrypt-success.json')
const eventEncryptSuccessJson = require('../events/encrypt-success-json.json')

describe('receive', function () {
  var spy, stub
  beforeEach(function () {
    spy = sinon.spy(response, 'build')
    stub = sinon.stub(database, 'put').callsFake((data, callback) => callback())
  })
  afterEach(function () {
    spy.restore()
    stub.restore()
  })
  describe('success', function () {
    it('html', function () {
      responseAssert('receive-success', eventReceiveSuccess, spy)
    })
    it('json', function () {
      responseAssert('receive-success', eventReceiveSuccessJson, spy)
    })
  })
  describe('error', function () {
    it('bad email', function () {
      responseAssert('receive-bad-email', eventReceiveBadEmail, spy)
    })
    it('no email', function () {
      responseAssert('receive-no-email', eventReceiveNoEmail, spy)
    })
    it('honeypot', function () {
      responseAssert('receive-honeypot', eventReceiveHoneypot, spy)
    })
  })
})

describe('encrypt', function () {
  var spy
  beforeEach(function () {
    spy = sinon.spy(response, 'build')
  })
  afterEach(function () {
    spy.restore()
  })
  describe('success', function () {
    it('html', function () {
      responseAssert('encrypt-success', eventEncryptSuccess, spy)
    })
    it('json', function () {
      responseAssert('encrypt-success', eventEncryptSuccessJson, spy)
    })
  })
})

function responseAssert (type, event, spy) {
  let data = receiveRequest.getParams(event)
  switch (type.split('-')[0]) {
    case 'receive':
      receiveHandler.handle(event, {}, sinon.stub())
      break
    case 'encrypt':
      encryptHandler.handle(event, {}, sinon.stub())
      data['_encrypted'] = encryption.encrypt(data['_email'])
      break
    default:
      logErrorAndExit('Route not recognised')
  }
  let routeDetails = route.getRouteDetails(type, data)
  assert(spy.calledOnce)
  let result = spy.firstCall.returnValue
  assert.equal(result.statusCode, routeDetails.statusCode)
  let expectedContentType = data['_format'] === 'json' ? 'application/json' : 'text/html'
  assert.equal(result.headers['Content-Type'], expectedContentType)
  assert.include(result.body, routeDetails.message)
}

function logErrorAndExit (error) {
  console.log(error)
  process.exit(1)
}

@@ -425,24 +425,86 @@
 /response')%0A
+const encryptHandler = require('../handlers/encrypt/handler')%0A
 const receiv
@@ -615,36 +615,42 @@
 quest')%0A
+%0A
 const e
+ventE
 ncrypt
-Handler
+Success
  = requi
@@ -660,36 +660,117 @@
 '../
-handlers/encrypt/handler
+events/encrypt-success.json')%0Aconst eventEncryptSuccessJson = require('../events/encrypt-success-json.json
 ')%0A
-%0A
 cons
@@ -1134,55 +1134,260 @@
 n')%0A
-const eventEncryptSuccess = require('../events/
+%0Adescribe('encrypt', function () %7B%0A  var spy%0A  beforeEach(function () %7B%0A    spy = sinon.spy(response, 'build')%0A  %7D)%0A  afterEach(function () %7B%0A    spy.restore()%0A  %7D)%0A  describe('success', function () %7B%0A    it('html', function () %7B%0A      responseAssert('
 encr
@@ -1393,37 +1393,26 @@
 rypt-success
-.json')%0Aconst
+',
  eventEncryp
@@ -1423,60 +1423,134 @@
 cess
-Json = require('../events/e
+, spy)%0A    %7D)%0A    it('json', function () %7B%0A      responseAssert('encrypt-success', eventE
 ncrypt
--s
+S
 uccess
--json.json'
+Json, spy)%0A    %7D)%0A  %7D)%0A%7D
 )%0A%0Ad
@@ -2439,425 +2439,8 @@
 %7D)%0A%0A
-describe('encrypt', function () %7B%0A  var spy%0A  beforeEach(function () %7B%0A    spy = sinon.spy(response, 'build')%0A  %7D)%0A  afterEach(function () %7B%0A    spy.restore()%0A  %7D)%0A  describe('success', function () %7B%0A    it('html', function () %7B%0A      responseAssert('encrypt-success', eventEncryptSuccess, spy)%0A    %7D)%0A    it('json', function () %7B%0A      responseAssert('encrypt-success', eventEncryptSuccessJson, spy)%0A    %7D)%0A  %7D)%0A%7D)%0A%0A
 func

move encrypt tests and imports above require tests