SRC_DIR = '../../../src/log/'

fs = require 'fs'
utils = require '../../TestUtils.coffee'
Addr64 = (require SRC_DIR + 'Addr64.coffee').Addr64
LogCache = (require SRC_DIR + 'LogCache.coffee').LogCache
LightOutputStream =
  (require SRC_DIR + '../database/impl/iterate/LightOutputStream.coffee').
  LightOutputStream
CompressedUnsignedLongByteIterable =
  (require SRC_DIR + 'iterate/CompressedUnsignedLongByteIterable.coffee').
  CompressedUnsignedLongByteIterable
DataIterator = (require SRC_DIR + 'DataIterator.coffee').DataIterator
LogUtil = (require SRC_DIR + 'LogUtil.coffee').LogUtil

bufferEqual = (b1, b2) ->
  l = Math.min b1.length, b2.length
  b = true
  for i in [0..l - 1]
    b = b && (b1[i] == b2[i])
  return b

exports.testCompressedSize = (test) ->
  test.expect 6
  test.equal CompressedUnsignedLongByteIterable.getCompressedSize$int(0), 1
  test.equal CompressedUnsignedLongByteIterable.getCompressedSize$int(1), 1
  test.equal CompressedUnsignedLongByteIterable.getCompressedSize$int(128), 2
  test.equal CompressedUnsignedLongByteIterable.getCompressedSize$int(16384), 3
  test.equal CompressedUnsignedLongByteIterable.getCompressedSize$int(16383), 2
  test.equal CompressedUnsignedLongByteIterable.getCompressedSize$int(25000), 3
  test.done()

exports.testWrite = (test) ->
  test.expect 6
  test.ok bufferEqual(
          CompressedUnsignedLongByteIterable.
          fillBytes$int$LightOutputStream(0, LightOutputStream.
          create$Buffer(new Buffer(10))),
          new Buffer([-128]))
  test.ok bufferEqual(
          CompressedUnsignedLongByteIterable.
          fillBytes$int$LightOutputStream(1, LightOutputStream.
          create$Buffer(new Buffer(10))),
          new Buffer([-127]))
  test.ok bufferEqual(
          CompressedUnsignedLongByteIterable.
          fillBytes$int$LightOutputStream(128, LightOutputStream.
          create$Buffer(new Buffer(10))),
          new Buffer([0, -127]))
  test.ok bufferEqual(
          CompressedUnsignedLongByteIterable.
          fillBytes$int$LightOutputStream(16384, LightOutputStream.
          create$Buffer(new Buffer(10))),
          new Buffer([0, 0, -127]))
  test.ok bufferEqual(
          CompressedUnsignedLongByteIterable.
          fillBytes$int$LightOutputStream(16383, LightOutputStream.
          create$Buffer(new Buffer(10))),
          new Buffer([127, -1]))
  test.ok bufferEqual(
          CompressedUnsignedLongByteIterable.
          fillBytes$int$LightOutputStream(25000, LightOutputStream.
          create$Buffer(new Buffer(10))),
          new Buffer([40, 67, -127]))
  test.done()

exports.testGet = (test) ->
  test.expect 26
  path = utils.getNewDirName()
  cache = LogCache.create$String$int$int$int path, 1024, 16, 10
  try
    fs.mkdirSync path, '0777'
  catch e
  b = new Buffer 1024
  stream = LightOutputStream.create$Buffer b
  for i in [0..20]
    CompressedUnsignedLongByteIterable.fillBytes$int$LightOutputStream 25000 + i,
            stream
  f = "00000000000"
  fd = fs.openSync path + f + LogUtil.LOG_FILE_EXTENSION, 'w'
  fs.writeSync fd, b, 0, b.length, 0
  fs.closeSync fd
  # compare first 5 numbers
  test.ok bufferEqual b, new Buffer(
          [40, 67, -127, 41, 67, -127, 42, 67, -127, 43, 67, -127, 44, 67,-127])
  itR = DataIterator.create$LogCache$Addr64 cache, Addr64.create$int$int 0, 0
  addrString = Addr64.addr64ToString$Addr64$int(itR.addr,
          LogUtil.LOG_NAME_BASE)
  CompressedUnsignedLongByteIterable.EMITTER.once 'getInt' + addrString, (value, newIt) =>
    test.equal value, 25000 + 0
    for i in [1..4]
      v = CompressedUnsignedLongByteIterable.getInt$ByteIterator$emit itR
      test.equal v, 25000 + i
    addrString = Addr64.addr64ToString$Addr64$int(itR.addr,
            LogUtil.LOG_NAME_BASE)
    CompressedUnsignedLongByteIterable.EMITTER.once 'getInt' + addrString, (value, newIt) =>
      test.equal value, 25000 + 5
      test.equal newIt.pageAddr.toFloat(), 16
      test.equal newIt.offset, 2
      test.equal itR.pageAddr.toFloat(), 16
      test.equal itR.offset, 2
      for i in [6..9]
        v = CompressedUnsignedLongByteIterable.getInt$ByteIterator$emit itR
        test.equal v, 25000 + i
      addrString = Addr64.addr64ToString$Addr64$int(itR.addr,
              LogUtil.LOG_NAME_BASE)
      CompressedUnsignedLongByteIterable.EMITTER.once 'getInt' + addrString, (value, newIt) =>
        test.equal value, 25000 + 10
        for i in [11..15]
          v = CompressedUnsignedLongByteIterable.getInt$ByteIterator$emit itR
          test.equal v, 25000 + i
        test.equal itR.pageAddr.toFloat(), 48
        test.equal itR.offset, 0
        test.done()
      v = CompressedUnsignedLongByteIterable.getInt$ByteIterator$emit itR
      test.equal v, undefined
    v = CompressedUnsignedLongByteIterable.getInt$ByteIterator$emit itR
    test.equal v, undefined
  v = CompressedUnsignedLongByteIterable.getInt$ByteIterator$emit itR
  test.equal v, undefined
