'use strict'
var path = require('path')
var fs = require('fs')
var os = require('os')
var Tail = require('tail-forever')
var glob = require('glob')
var logger = require('./logger.js')

function FileManager (options) {
  this.filePointers = this.readFilePointers()
  this.filesToWatch = []
  this.fileNamesToWatch = []
  this.options = options
  this.scanCounter = 0
  this.stats = {}
}

function getFilesizeInBytes (filename) {
  try {
    var stats = fs.statSync(filename)
    return stats.size
  } catch (fsErr) {
    return -1
  }
}

FileManager.prototype.tailFiles = function (fileList) {
  fileList.forEach(this.tailFile.bind(this))
}
FileManager.prototype.getTempDir = function () {
  return process.env.LOGSENE_TMP_DIR || os.tmpDir()
}

FileManager.prototype.getTailPosition = function (file) {
  var storedPos = this.filePointers[file]
  if (!storedPos) {
    logger.debug('no position stored for ' + file)
    // tail from end of file
    return {start: getFilesizeInBytes(file)}
  } else {
    var fd = fs.openSync(file, 'r')
    var stat = fs.fstatSync(fd)
    if (stat.ino === storedPos.inode) {
      return {start: storedPos.pos, inode: storedPos.inode}
    } else {
      logger.debug('Watching file ' + file + ' inode changed, set tail position = 0')
      return {start: 0}
    }
  }
}

FileManager.prototype.tailFilesFromGlob = function  (globPattern, scanTime) {
  if (globPattern) {
    glob(globPattern, {strict: false, silent: false}, function (err, files) {
      if (!err) {
        this.tailFiles(files)
      } else {
        logger.error('Error in glob file patttern ' + globPattern + ': ' + err.message)
      }
    }.bind(this))
    if (!this.globPattern && scanTime>0) {
      this.globPattern=globPattern
      setInterval(function () {
        this.scanCounter = 1
        this.tailFilesFromGlob(this.globPattern, scanTime)
        this.savePositions()
      }.bind(this), scanTime)
    }
  }
}

FileManager.prototype.tailFile = function (file) {
  var tail = null
  var pos = {start:0}
  if (this.fileNamesToWatch.indexOf(file) > -1) {
    // check if we watch this file already
    return null
  } else {
    
  }
  try {
    pos = this.getTailPosition(file)
  } catch (error) {
    // file might not exists, we ignore it and start watching 
    pos = {start: 0}
  }
  if (this.scanCounter > 0) {
     // a new file matched the glob pattern
     // reading from begin of file
     logger.log('New file detected: ' + file)
     pos = {start: 0}
  }
  try {
    if (pos.start == -1) {
      // there was no postion stored, let's start from the beginning
      // throw new Error('File ' + file + ' does not exist.')
      pos.start = 0
    }
    tail = new Tail(file, pos)
    this.filesToWatch.push(tail)
    this.fileNamesToWatch.push(file)
    tail.on('line', function (line) {
      this.stats[file] = (this.stats[file]||0) +1
      this.options.parseLine(line, file, this.options.log)
    }.bind(this))
    tail.on('error', function (error) {
      logger.log('ERROR tailing file ' + file + ': ' + error)  
    })
    logger.log('Watching file:' + file + ' from position: ' + pos.start)
    return tail
  } catch (error) {
    //log('ERROR tailing file ' + file + ': ' + error)
    return null
  }
}

FileManager.prototype.terminate = function () {
  this.savePositions()
}
 
FileManager.prototype.savePositions = function () {
  var filePositions = this.filesToWatch.map(function (tailObj) {
    try {
      var position = tailObj.unwatch()
      position.fileName = tailObj.filename
      logger.log('Stop watching ' + tailObj.filename + ' inode: ' + position.inode + ' pos:' + position.pos)
      return position 
    } catch (fileExistsError) {
      // file got removed
      return null
    }
  })
  try {
    var fileName = path.join(this.getTempDir(), 'logagentTailPointers.json')
    fs.writeFileSync(fileName, JSON.stringify(filePositions))
    logger.log('File positions stored in: ' + fileName)
  } catch (err) {
    logger.log('error writing file pointers:' + err)
  }
}

FileManager.prototype.readFilePointers = function () {
  var filePointers = {}
  try {
    var fileName = path.join(this.getTempDir(), 'logagentTailPointers.json')
    var fp = fs.readFileSync(fileName)
    var filePointerArr = JSON.parse(fp)
    filePointerArr.forEach(function (f) {
      filePointers[f.fileName] = {pos: f.pos, inode: f.inode}
    })
    logger.log(filePointers)
    fs.unlinkSync(fileName)
  } catch (err) {
    logger.log('Error reading file pointers: ' + err)
  }
  return filePointers
}

module.exports = FileManager

@@ -377,16 +377,85 @@
 ts = %7B%7D%0A
+  this.cliArgs = options.cliArgs %7C%7C %7B%7D%0A  this.sigTermHandled = false%0A
 %7D%0A%0Afunct
@@ -1922,37 +1922,8 @@
 me)%0A
-        this.savePositions()%0A
     
@@ -2984,16 +2984,18 @@
  tail.on
+ce
 ('error'
@@ -3080,16 +3080,25 @@
 ror)
-  
 %0A    %7D
+.bind(this)
 )%0A  
@@ -3326,24 +3326,85 @@
 nction () %7B%0A
+  if (!this.sigTermHandled) %7B%0A    this.sigTermHandled=true%0A  
   this.saveP
@@ -3414,16 +3414,20 @@
 tions()%0A
+  %7D%0A
 %7D%0A %0AFile
@@ -4493,32 +4493,114 @@
     
-logger.log(filePointers)
+if (Object.keys(filePointers).length%3E0) %7B%0A      logger.debug(JSON.stringify(filePointers,null,'%5Ct'))%0A    %7D
 %0A   
@@ -4690,24 +4690,30 @@
 ers: ' + err
+.stack
 )%0A  %7D%0A  retu

handle sigterm only once