import getLogger, { QuizEventsLogger } from '../QuizEventsLogger'
import {
  fakeKinesisConfigCreator,
  fakeStreamQueueCreator
} from './kinesisTests'

describe('event logging tools', () => {
  describe('QuizEventsLogger', () => {
    const fakeStreamQueue = fakeStreamQueueCreator()
    const quizEventLogger = new QuizEventsLogger(fakeStreamQueue)

    beforeEach(() => {
      sinon.stub(fakeStreamQueue, 'push')
    })

    afterEach(() => {
      fakeStreamQueue.push.restore()
    })

    // Public API is #enqueueEvent
    context('valid data types', () => {
      const event = { eventType: 'EVENT' }
      it('queues up data', () => {
        quizEventLogger.enqueueEvent(event)
        expect(fakeStreamQueue.push.called).to.be.true()
      })
    })

    context('invalid data types', () => {
      const event = { eventType: 'NOT_AN_EVENT' }
      it('throws up on bad data', () => {
        const trigger = () => { quizEventLogger.enqueueEvent(event) }
        expect(trigger).to.throw(Error, /Unable to locate a valid StreamQueue for event type NOT_AN_EVENT/)
        expect(fakeStreamQueue.push.called).to.be.false()
      })
    })

    context('needsRefresh', () => {
      let clock = null

      beforeEach(() => {
        clock = sinon.useFakeTimers()
      })

      afterEach(() => {
        clock.restore()
      })

      it('is false just after having been built', () => {
        expect(quizEventLogger.needsRefresh()).to.be.false()
      })

      it('is true after 10 minutes have elapsed', () => {
        const staleQuizEventsLogger = new QuizEventsLogger(fakeStreamQueue)
        clock.tick(600001)
        expect(staleQuizEventsLogger.needsRefresh()).to.be.true()
      })
    })
  })

  describe('getLogger', () => {
    let clock = null

    beforeEach(() => {
      clock = sinon.useFakeTimers()
    })

    afterEach(() => {
      clock.restore()
    })

    const kinesisClientGetterStub = sinon.stub()
    kinesisClientGetterStub.withArgs('1')
      .onFirstCall()
      .returns(fakeKinesisConfigCreator())
      .onSecondCall()
      .returns(fakeKinesisConfigCreator())

    it('caches loggers until they expire', async () => {
      const logger = await getLogger('1', kinesisClientGetterStub)
      const logger2 = await getLogger('1', kinesisClientGetterStub)

      expect(logger).to.be.an.instanceof(QuizEventsLogger)
      expect(logger2).to.equal(logger)

      clock.tick(600001)

      const logger3 = await getLogger('1', kinesisClientGetterStub)
      expect(logger3).to.be.an.instanceOf(QuizEventsLogger)
      expect(logger3).to.not.equal(logger2)
    })
  })
})
