chai      = require 'chai'
expect    = chai.expect
sinon     = require 'sinon'
sandbox   = sinon.sandbox.create()
sinonChai = require 'sinon-chai'
chai.use sinonChai

fs = require 'fs'
lowdb = require 'lowdb'

describe 'LowDB Store Adapter', ->
  lowDbStore = null

  before ->
    LowDbStore = require './lowdb_store'
    lowDbStore = new LowDbStore


  afterEach ->
    sandbox.restore()


  options = null
  domainEvent =
    name: 'SomethingHappened'
    aggregate:
      id: 23
      name: 'Example'

  before (done) ->
    options =
      path: 'db.json'
    lowDbStore.initialize 'exampleContext', options, (err) ->
      done()


  beforeEach ->
    fs.writeFileSync options.path, "{}"
    lowDbStore.db.load options.path


  describe 'domain events', ->
    describe '#saveDomainEvent', ->
      it 'should save the given doc', (done) ->
        lowDbStore.saveDomainEvent domainEvent, (err, _domainEvent) ->
          expect(_domainEvent).to.deep.equal domainEvent
          done()


    describe 'find', ->
      beforeEach (done) ->
        lowDbStore.saveDomainEvent domainEvent, ->
          done()


      describe '#findAllDomainEvents', ->
        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findAllDomainEvents (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


      describe '#findDomainEventsByName', ->
        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByName 'SomethingHappened', (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByName ['SomethingHappened'], (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


      describe '#findDomainEventsByAggregateId', ->
        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByAggregateId 23, (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByAggregateId [23], (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


      describe '#findDomainEventsByAggregateName', ->
        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByAggregateName 'Example', (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByAggregateName ['Example'], (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


      describe '#findDomainEventsByNameAndAggregateId', ->
        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByNameAndAggregateId 'SomethingHappened', 23, (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


        it 'should find the previously saved domainevent', (done) ->
          lowDbStore.findDomainEventsByNameAndAggregateId ['SomethingHappened'], [23], (err, domainEvents) ->
            expect(domainEvents).to.deep.equal [
              domainEvent
            ]
            done()


  describe 'projection stores', ->

    describe '#getProjectionStore', ->
      it 'should callback with the collection', (done) ->
        lowDbStore.getProjectionStore 'exampleProjection', (err, collection) ->
          expect(collection).to.be.an.instanceof Object
          done()


    describe '#clearProjectionStore', ->
      it 'should clear the collection and callback', (done) ->
        lowDbStore.getProjectionStore 'exampleProjection', (err, projection) ->
          projection.insert {wat: 'wat'}

          lowDbStore.clearProjectionStore 'exampleProjection', ->
            lowDbStore.getProjectionStore 'exampleProjection', (err, projection) ->
              expect(projection.where().value().length).to.equal 0
              done()