/* global it, describe, beforeEach, afterEach */
const assert = require('assert')
const os = require('os')
const path = require('path')
const fs = require('fs')
const LOG = require('./index')
const hostname = os.hostname()
function getDate () {
  var tzoffset = (new Date()).getTimezoneOffset() * 60000 // offset in milliseconds
  var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -1)
  return localISOTime.split('.')[0].trim()
}
const manualhostname = 'testhost'
const name = 'testapp'
let file = 'testfile'
const filePath = '/tmp'

let orginialFile
let log
let line
let testline
describe('@br/Log', () => {
  describe(': No Options', () => {
    beforeEach(() => {
      console.log('create Object')
      log = new LOG()
    })
    afterEach(() => {
      console.log('destroy Object')
      log = undefined
    })
    describe(': Info', () => {
      it('should output empty line - standard log-level without options is warn', () => {
        line = log.info('testline')
        assert.equal(line, '')
      })
    })
    describe(': Notice', () => {
      it('should output empty line - standard log-level without options is warn', () => {
        line = log.notice('testline')
        assert.equal(line, '')
      })
    })
    describe(': Warn', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tWARN\ttestline'
        line = log.warn('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Error', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tERROR\ttestline'
        line = log.error('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Fatal', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tFATAL\ttestline'
        line = log.fatal('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Debug', () => {
      it('should output the given Line', () => {
        line = log.debug('testline')
        assert.equal(line, '')
      })
    })
  })
  describe(': Hostname Set', () => {
    beforeEach(() => {
      console.log('create Object')
      log = new LOG({
        hostname: manualhostname
      })
    })
    afterEach(() => {
      console.log('destroy Object')
      log = undefined
    })
    describe(': Info', () => {
      it('should output the given Line', () => {
        line = log.info('testline')
        assert.equal(line, '')
      })
    })
    describe(': Notice', () => {
      it('should output the given Line', () => {
        line = log.notice('testline')
        assert.equal(line, '')
      })
    })
    describe(': Warn', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + manualhostname + '\t@br/log\tWARN\ttestline'
        line = log.warn('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Error', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + manualhostname + '\t@br/log\tERROR\ttestline'
        line = log.error('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Fatal', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + manualhostname + '\t@br/log\tFATAL\ttestline'
        line = log.fatal('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Debug', () => {
      it('should output the given Line', () => {
        line = log.debug('testline')
        assert.equal(line, '')
      })
    })
  })
  describe(': Name Set', () => {
    beforeEach(() => {
      console.log('create Object')
      log = new LOG({
        name: name
      })
    })
    afterEach(() => {
      console.log('destroy Object')
      log = undefined
    })
    describe(': Info', () => {
      it('should output the given Line', () => {
        line = log.info('testline')
        assert.equal(line, '')
      })
    })
    describe(': Notice', () => {
      it('should output the given Line', () => {
        line = log.notice('testline')
        assert.equal(line, '')
      })
    })
    describe(': Warn', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t' + name + '\tWARN\ttestline'
        line = log.warn('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Error', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t' + name + '\tERROR\ttestline'
        line = log.error('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Fatal', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t' + name + '\tFATAL\ttestline'
        line = log.fatal('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Debug', () => {
      it('should output the given Line', () => {
        line = log.debug('testline')
        assert.equal(line, '')
      })
    })
  })
  describe(': File Set', () => {
    beforeEach(() => {
      console.log('create Object')
      log = new LOG({
        path: filePath,
        file: file
      })
      orginialFile = file
      file = path.join(filePath, file)
      try {
        fs.accessSync(file, fs.constants.R_OK | fs.constants.W_OK)
      } catch (error) {
        fs.writeFileSync(file, '', { flag: 'wx' }) // Create File if not exists
      }
    })
    afterEach(() => {
      console.log('destroy Object')
      log = undefined
      fs.truncateSync(file) // Clean Up, clear contents
      file = orginialFile
    })
    describe(': Info', () => {
      it('should output the given Line to the file', function (done) {
        log.info('testline')
        setTimeout(() => {
          line = fs.readFileSync(file, 'utf-8')
          assert.equal(line, '')
          done()
        }, 10)
      })
    })
    describe(': Notice', () => {
      it('should output the given Line to the file', function (done) {
        log.notice('testline')
        setTimeout(() => {
          line = fs.readFileSync(file, 'utf-8')
          assert.equal(line, '')
          done()
        }, 10)
      })
    })
    describe(': Warn', () => {
      it('should output the given Line to the file', function (done) {
        testline = getDate() + '\t' + hostname + '\t@br/log\tWARN\ttestline\n'
        log.warn('testline')
        setTimeout(() => {
          line = fs.readFileSync(file, 'utf-8')
          assert.equal(line, testline)
          done()
        }, 10)
      })
    })
    describe(': Error', () => {
      it('should output the given Line to the file', function (done) {
        testline = getDate() + '\t' + hostname + '\t@br/log\tERROR\ttestline\n'
        log.error('testline')
        setTimeout(() => {
          line = fs.readFileSync(file, 'utf-8')
          assert.equal(line, testline)
          done()
        }, 10)
      })
    })
    describe(': Fatal', () => {
      it('should output the given Line to the file', function (done) {
        testline = getDate() + '\t' + hostname + '\t@br/log\tFATAL\ttestline\n'
        log.fatal('testline')
        setTimeout(() => {
          line = fs.readFileSync(file, 'utf-8')
          assert.equal(line, testline)
          done()
        }, 10)
      })
    })
    describe(': Debug', () => {
      it('should output the given Line to the file', function (done) {
        log.debug('testline')
        setTimeout(() => {
          line = fs.readFileSync(file, 'utf-8')
          assert.equal(line, '')
          done()
        }, 10)
      })
    })
  })
  describe(': Loglevel DEBUG Set', () => {
    beforeEach(() => {
      console.log('create Object')
      log = new LOG({
        loglevel: 'DEBUG'
      })
    })
    afterEach(() => {
      console.log('destroy Object')
      log = undefined
    })
    describe(': Info', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tINFO\ttestline'
        line = log.info('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Notice', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tNOTICE\ttestline'
        line = log.notice('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Warn', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tWARN\ttestline'
        line = log.warn('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Error', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tERROR\ttestline'
        line = log.error('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Fatal', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tFATAL\ttestline'
        line = log.fatal('testline')
        assert.equal(line, testline)
      })
    })
    describe(': Debug', () => {
      it('should output the given Line', () => {
        testline = getDate() + '\t' + hostname + '\t@br/log\tDEBUG\ttestline'
        line = log.debug('testline')
        assert.equal(line, testline)
      })
    })
  })
})