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

fs = require 'fs'
utils = require '../TestUtils.coffee'
addr64 = require SRC_DIR + 'addr64'
Addr64 = addr64.Addr64
WriteLogable = (require SRC_DIR + 'write_logable').LoggableToWrite
Log = (require SRC_DIR + 'log').Log

N = 100
Nstep = N / 5
t = 0

oneTest = (test, k, n) =>
  path = utils.getNewDirName()
  log = new Log path, 10, 6, 100
  addr = log.addr
  addrs = new Object()

  killFile = (addr, size) =>
    log.parseAddr$Addr64 addr
    b = new Buffer size
    for i in [0..size - 1]
      b[i] = Math.ceil(Math.random() * 255)
    fd = fs.openSync log.fn, 'w'
    fs.writeSync fd, b, 0, b.length, 0
    fs.closeSync fd

  addr = log.addr

  log.once 'close', () =>
    log.once 'analize', (lastAddr) =>
      test.ok addrs[N / Nstep].equals lastAddr
      log.parseAddr$Addr64 addr
      killFile addr, log.offset
      log = new Log path, 10, 6, 100
      log.once 'analize', (lastAddr2) =>
        test.ok addrs[N / Nstep - 1].equals lastAddr2
        while addr.toFloat() > log.addr.toFloat() * 3 / 10
          addr = addr.plus(-1024)
          killFile addr, 1024
        log = new Log path, 10, 6, 100
        log.once 'analize', (lastAddr3) =>
          test.ok addrs[1].equals lastAddr3
          while addr.toFloat() >= 1024
            addr = addr.plus(-1024)
            killFile addr, 1024
          log = new Log path, 10, 6, 100
          log.once 'analize', (lastAddr4) =>
            test.equal lastAddr4, undefined
            t += 1
            if t == n
              test.done()
          log.analize()
        log.analize()
      log.analize()
    log.analize()

  writeFromJtoK = (j, k) =>
    log.once 'commit', () =>
      writeFromJtoK j + Nstep, k + Nstep
    if k <= N
      for i in [j..k]
        b = new Buffer("Some useless test string with number " + i.toString())
        d = new WriteLogable 2, 2, b
        addr = log.write$Loggable d
      addrs[k / Nstep] = addr
      log.commit()
    else
      log.close()
  writeFromJtoK 1, Nstep

exports.testCorruption = (test) =>
  n = 20
  test.expect 4 * n
  for k in [1..n]
    oneTest test, k, n
