var fs = require('fs')
var path = require('path')
var merge = require('lodash.merge')

module.exports = function() {
  let configDefaults = path.join(path.dirname(require.main.filename), 'config.defaults.json')
  let configLocal = path.join(path.dirname(require.main.filename), 'config.json')
  
  let config = {}
  
  const objectDeepKeys = function (obj) {
    return Object.keys(obj).filter(key => obj[key] instanceof Object).map(key => objectDeepKeys(obj[key]).map(k => `${key}.${k}`)).reduce((x, y) => x.concat(y), Object.keys(obj))
  }
  
  const set = function(obj, path, value) {
    var schema = obj  // a moving reference to internal objects within obj
    var pList = path.split('.')
    var len = pList.length
    for(var i = 0; i < len-1; i++) {
        var elem = pList[i]
        if( !schema[elem] ) schema[elem] = {}
        schema = schema[elem]
    }
    schema[pList[len-1]] = value
}

  try {
    fs.accessSync(configDefaults)
    config = JSON.parse(fs.readFileSync(configDefaults, 'utf8'))
  } catch(error) {
    console.log('No File ' + configDefaults)
  }
  
  try {
    fs.accessSync(configLocal)
    config = merge(config, JSON.parse(fs.readFileSync(configLocal, 'utf8')))
  } catch (error) {
    console.log('No File ' + configLocal)
  }
  
  let keys = objectDeepKeys(config)
  for (let index = 0; index < keys.length; index++) {
    const element = keys[index]
    let env = process.env[element.toUpperCase().replace(/\./g, '_')]
    if (env) {
      env = (env == 'true') ? true : env
      env = (env == 'false') ? false : env
      set(config, element, env)
    }
  }

  config.reload = function () {
    try {
      fs.accessSync(configDefaults)
      config = merge(this, JSON.parse(fs.readFileSync(configDefaults, 'utf8')))
    } catch(error) {
      console.log('No File ' + configDefaults)
    }
    try {
      fs.accessSync(configLocal)
      config = merge(this, JSON.parse(fs.readFileSync(configLocal, 'utf8')))
    } catch (error) {
      console.log('No File ' + configLocal)
    }
    let keys = objectDeepKeys(this)
    for (let index = 0; index < keys.length; index++) {
      const element = keys[index]
      const env = process.env[element.toUpperCase().replace('.', '_')]
      if (env) {
        set(this, element, env)
      }
    }
  }

  return config
}