'use strict';

require('js-yaml')

var log = require('./log')

function ConfigurationReader() {

  var self = this

  /*
   * Merges all values from the second parameter into the given configuration.
   * If configuration already has the key, it will *not* be overwritten with the
   * corresponding value from defaults.
   */
  function recursiveMerge(configuration, defaults) {
    // iterate through all key-value-pairs in defaults
    for (var key in defaults) {
      if (defaults.hasOwnProperty(key)) {
        var defaultValue = defaults[key]
        // if it is an object... (that is, a non-leave in the config tree)
        if (typeof defaultValue === 'object') {
          // ... and not present in the current configuration...
          if (!configuration[key] || typeof configuration[key] !== 'object') {
            // ... we create an empty array in the current configuration
            configuration[key] = {}
          }
          // ... and recurse deeper into the structure
          recursiveMerge(configuration[key], defaults[key])
        // primitive values (strings, numbers, ..., everything that is neither
        // object or function) are handled here: If it is not present in the
        // current configuration we merge it.
        } else if (typeof defaultValue !== 'function') {
          if (!configuration[key]) {
            configuration[key] = defaults[key]
          }
        }
      }
    }
  }

  this.read = function(filename) {
    /* load configuration from yaml */
    try {
      this.configuration = require(filename);
    } catch (err) {
      this.configuraiton = {}
      log.error(err)
      log.warn('Could not find configuration file %s, will use default ' +
          'configuration values.', filename)
      return
    }

    /* use defaults for configuration values that have not been configured */
    recursiveMerge(this.configuration, getDefaults())
    log.debug('Core configuration (read from %s, merged with defaults):\n',
        filename, this.configuration)

    // TODO Is this a responsibility of the config reader or of the config
    // object? This also decides wether to inject the config reader or only the
    // config object into other components.
    var merge = recursiveMerge
    this.mergeDefaultsIntoCurrentConfiguration =
        function(defaults) {
      merge(self.configuration, defaults)
    }
  }

  function getDefaults() {
    return {
      core: {
        port: 1302,
        bindAddress: '0.0.0.0',
        backend: './backends/node_dirty_backend'
      }
    }
  }
}

module.exports = ConfigurationReader

@@ -514,180 +514,372 @@
     
-var defaultValue = defaults%5Bkey%5D%0A        // if it is an object... (that is, a non-leave in the config tree)%0A        if (typeof defaultValue === 'object') %7B%0A      
+if (typeof defaults%5Bkey%5D === 'object') %7B%0A          mergeObject(configuration, defaults, key)%0A        %7D else if (typeof defaults%5Bkey%5D !== 'function') %7B%0A          mergePrimitive(configuration, defaults, key)%0A        %7D%0A      %7D%0A    %7D%0A  %7D%0A%0A  function mergeObject(configuration, defaults, key) %7B%0A    // if it is an object (that is, a non-leave in the config tree)%0A
     //
- ...
  and
@@ -923,22 +923,16 @@
 tion...%0A
-      
     if (
@@ -992,30 +992,24 @@
 'object') %7B%0A
-      
       // ...
@@ -1063,22 +1063,16 @@
 uration%0A
-      
       co
@@ -1097,30 +1097,18 @@
  %7B%7D%0A    
-      %7D%0A      
+%7D%0A
     // .
@@ -1148,22 +1148,16 @@
 ructure%0A
-      
     recu
@@ -1200,26 +1200,86 @@
 lts%5Bkey%5D)%0A  
-  
+%7D%0A %0A  function mergePrimitive(configuration, defaults, key) %7B%0A
     // primi
@@ -1341,20 +1341,16 @@
 neither%0A
-    
     // o
@@ -1414,20 +1414,16 @@
  in the%0A
-    
     // c
@@ -1460,71 +1460,8 @@
 it.%0A
-        %7D else if (typeof defaultValue !== 'function') %7B%0A      
     
@@ -1493,22 +1493,16 @@
 %7B%0A      
-   
-   
 configur
@@ -1536,44 +1536,15 @@
     
-      %7D%0A        %7D%0A      %7D%0A    
 %7D%0A  %7D%0A
+ 
 %0A  t

fix cyclomatic complexity (jshint)