'use strict';

var config;
var modules;

// Everything that uses the config should be reading it when relevant rather than
// just at the beginning, so we keep the reference for the main object and just
// change all of its properties to match the new config.
function update(conf) {
  var newKeys = Object.keys(conf);

  Object.keys(config).forEach(function (key) {
    if (newKeys.indexOf(key) < 0) {
      delete config[key];
    } else {
      config[key] = conf[key];
    }
  });

  console.log('config update', JSON.stringify(config));
  Object.values(modules).forEach(function (mod) {
    if (typeof mod.updateConf === 'function') {
      mod.updateConf(config);
    }
  });
}

function create(conf) {
  var PromiseA = require('bluebird');
  var OAUTH3 = require('../packages/assets/org.oauth3');
  require('../packages/assets/org.oauth3/oauth3.domains.js');
  require('../packages/assets/org.oauth3/oauth3.dns.js');
  require('../packages/assets/org.oauth3/oauth3.tunnel.js');
  OAUTH3._hooks = require('../packages/assets/org.oauth3/oauth3.node.storage.js');

  config = conf;
  var deps = {
    messenger: process
  , PromiseA: PromiseA
  , OAUTH3: OAUTH3
  , request: PromiseA.promisify(require('request'))
  , recase: require('recase').create({})
    // Note that if a custom createConnections is used it will be called with different
    // sets of custom options based on what is actually being proxied. Most notably the
    // HTTP proxying connection creation is not something we currently control.
  , net: require('net')
  };

  modules = {
    storage:  require('./storage').create(deps, conf)
  , socks5:   require('./socks5-server').create(deps, conf)
  , ddns:     require('./ddns').create(deps, conf)
  , mdns:     require('./mdns').create(deps, conf)
  , udp:      require('./udp').create(deps, conf)
  , tcp:      require('./tcp').create(deps, conf)
  , stunneld: require('./tunnel-server-manager').create(deps, config)
  };
  Object.assign(deps, modules);

  process.removeListener('message', create);
  process.on('message', update);
}

process.on('message', create);