fs = require 'fs'
Addr64 = (require './Addr64.coffee').Addr64

# This class contains simple util functions, e.g. converting address to filename
# and vice versa.
class LogUtil
  @LOG_BLOCK_ALIGNMENT: 1024 # log files are aligned by kilobytes
  @LOG_FILE_NAME_WITH_EXT_LENGTH: 14
  @LOG_FILE_NAME_LENGTH: 11
  @LOG_FILE_EXTENSION: ".xd"
  @LOG_NAME_BASE: 32

  # Generates file name (without directory) from address.
  #
  # @param address Addr64 object
  # @return filename
  @getLogFilename$Addr64: (address) ->
    fn = Addr64.addr64ToString$Addr64$int address, @LOG_NAME_BASE
    fn = fn.substr 0, @LOG_FILE_NAME_LENGTH
    fn = fn + @LOG_FILE_EXTENSION
    return fn

  # Gets address from log filename.
  #
  # @param logFileName name of log file (without directory).
  # @return address of beginning of this file.
  @getAddress$String: (logFilename) ->
    logFilename = logFilename.substr(0, @LOG_FILE_NAME_LENGTH) + "00" +
            @LOG_FILE_EXTENSION
    addr = (Addr64.stringToAddr64$String$int logFilename, @LOG_NAME_BASE)
    return addr

  # Gets list of files in directory.
  #
  # @param directory the place where log is proposed to be.
  # @return list of only log files in this directory.
  @listFiles$String: (directory) ->
    try
      fs.mkdirSync directory, '0777'
    catch e
    rawFiles = fs.readdirSync directory
    files = rawFiles.filter (element, index, array) =>
      return element.indexOf(@LOG_FILE_EXTENSION) != -1
    return files

  # Gets high address in the current directory (i.e. the address of the end
  # of the log).
  #
  # @param directory the place where log is proposed to be.
  # @return address.
  @getHighAddress$String: (directory) ->
    files = @listFiles$String directory
    if files.length != 0
      files.sort()
      lastFile = files[files.length - 1]
      stats = fs.statSync directory + lastFile
      addr = (LogUtil.getAddress$String lastFile).plus$int(stats.size)
    else
      addr = Addr64.create$int$int 0, 0
    return addr

exports.LogUtil = LogUtil