import sinon from 'sinon'
import {assert} from 'chai'
import history from '../src/history'
import fs from 'fs'

describe('history', function() {
  let fsStub, resetFs, now, clock, currentConf

  beforeEach(() => {
    currentConf = {
      history: [{
        from: 'Address 1',
        to: 'Address 2',
        count: 1,
        timestamp: 100
      },
      {
        from: 'Address 2',
        to: 'Address 3',
        count: 2,
        timestamp: 200
      },
      {
        from: 'Address 3',
        to: 'Address 4',
        count: 3,
        timestamp: 300
      }]
    }
    fsStub = {
      readFile: sinon.spy((file, encoding, cb) => cb(null, JSON.stringify(currentConf))),
      writeFile: sinon.spy((file, data, cb) => cb(null))
    }
    resetFs = history.__Rewire__('fs', fsStub)
    now = Date.now()
    clock = sinon.useFakeTimers(now);
  })

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

  describe('addToHistory()', () => {
    it('should write history to configuration file', async () => {
      await history.add('Address 1', 'Address 2')
      const call = fsStub.writeFile.getCall(0)
      assert.isOk(call.args[0].endsWith('.routahe'))
    })

    it('should add new route to history', async () => {
      const expectedConf = {
        history: [...currentConf.history, {
          from: 'New address 1',
          to: 'New address 2',
          count: 1,
          timestamp: now
        }]
      }
      await history.add('New address 1', 'New address 2')
      const newConf = fsStub.writeFile.getCall(0).args[1]
      assert.deepEqual(JSON.parse(newConf), expectedConf)
    })

    it('should increment counter and timestamp of existing route', async () => {
      const expectedConf = {
        history: [{
            from: 'Address 1',
            to: 'Address 2',
            count: 2,
            timestamp: now
          },
          ...currentConf.history.slice(1)
        ]
      }
      await history.add('Address 1', 'Address 2')
      const newConf = fsStub.writeFile.getCall(0).args[1]
      assert.deepEqual(JSON.parse(newConf), expectedConf)
    })
  })

  describe('readHistory()', () => {
    it('should read history from configuration file', async () => {
      await history.get()
      const call = fsStub.readFile.getCall(0)
      assert.isOk(call.args[0].endsWith('.routahe'))
    })

    it('should return route history', async () => {
      const historyData = await history.get()
      assert.deepEqual(historyData, currentConf.history)
    })

    it('should return empty history if configuration file does not exist', async () => {
      fsStub.readFile = (file, encoding, cb) => cb({code: 'ENOENT'})
      const historyData = await history.get()
      assert.deepEqual(historyData, [])
    })
  })

  describe('topRoute()', () => {
    it('should return route with highest usage count', async () => {
      const top = currentConf.history[2]
      let route = await history.topRoute()
      assert.deepEqual(route, top)

      currentConf.history = [top, currentConf.history[1], currentConf.history[0]]
      route = await history.topRoute()
      assert.deepEqual(route, top)
    })

    it('should return null if history is empty', async () => {
      currentConf.history = []
      const route = await history.topRoute()
      assert.isNull(route)
    })
  })

  describe('latestRoute()', () => {
    it('should return route with latest timestamp', async () => {
      const latest = currentConf.history[2]
      let route = await history.latestRoute()
      assert.deepEqual(route, latest)

      currentConf.history = [latest, currentConf.history[1], currentConf.history[0]]
      route = await history.latestRoute()
      assert.deepEqual(route, latest)
    })

    it('should return null if history is empty', async () => {
      currentConf.history = []
      const route = await history.latestRoute()
      assert.isNull(route)
    })
  })
})

@@ -178,19 +178,12 @@
 k, c
-urrentC
 onf%0A
+
 %0A  b
@@ -205,23 +205,16 @@
  %7B%0A    c
-urrentC
 onf = %7B%0A
@@ -649,23 +649,16 @@
 ingify(c
-urrentC
 onf))),%0A
@@ -1257,31 +1257,24 @@
 story: %5B...c
-urrentC
 onf.history,
@@ -1852,23 +1852,16 @@
     ...c
-urrentC
 onf.hist
@@ -2062,32 +2062,497 @@
 f)%0A    %7D)%0A  %7D)%0A%0A
+  it('should use case insensitive address matching', async () =%3E %7B%0A      const expectedConf = %7B%0A        history: %5B%7B%0A            from: 'Address 1',%0A            to: 'Address 2',%0A            count: 2,%0A            timestamp: now%0A          %7D,%0A          ...conf.history.slice(1)%0A        %5D%0A      %7D%0A      await history.add('ADDRESS 1', 'aDdResS 2')%0A      const newConf = fsStub.writeFile.getCall(0).args%5B1%5D%0A      assert.deepEqual(JSON.parse(newConf), expectedConf)%0A    %7D)%0A%0A
   describe('read
@@ -2907,23 +2907,16 @@
 yData, c
-urrentC
 onf.hist
@@ -3302,31 +3302,24 @@
 onst top = c
-urrentC
 onf.history%5B
@@ -3399,39 +3399,32 @@
 e, top)%0A%0A      c
-urrentC
 onf.history = %5Bt
@@ -3428,23 +3428,16 @@
  %5Btop, c
-urrentC
 onf.hist
@@ -3437,39 +3437,32 @@
 nf.history%5B1%5D, c
-urrentC
 onf.history%5B0%5D%5D%0A
@@ -3605,39 +3605,32 @@
  () =%3E %7B%0A      c
-urrentC
 onf.history = %5B%5D
@@ -3839,23 +3839,16 @@
 test = c
-urrentC
 onf.hist
@@ -3938,39 +3938,32 @@
 latest)%0A%0A      c
-urrentC
 onf.history = %5Bl
@@ -3970,23 +3970,16 @@
 atest, c
-urrentC
 onf.hist
@@ -3987,23 +3987,16 @@
 ry%5B1%5D, c
-urrentC
 onf.hist
@@ -4158,22 +4158,15 @@
 %3E %7B%0A
+
       c
-urrentC
 onf.

Add test for case insensitive matching. Test cleanup.