'use strict';
var _ = require('lodash');

var BufferUtil = require('./util/buffer');
var JSUtil = require('./util/js');
var networks = [];
var networkMaps = {};

/**
 * A network is merely a map containing values that correspond to version
 * numbers for each bitcoin network. Currently only supporting "livenet"
 * (a.k.a. "mainnet") and "testnet".
 * @constructor
 */
function Network() {}

Network.prototype.toString = function toString() {
  return this.name;
};

/**
 * @function
 * @member Networks#get
 * Retrieves the network associated with a magic number or string.
 * @param {string|number|Network} arg
 * @param {string|Array} keys - if set, only check if the magic number associated with this name matches
 * @return Network
 */
function getNetwork(arg, keys) {
  if (~networks.indexOf(arg)) {
    return arg;
  }
  if (keys) {
    if (!_.isArray(keys)) {
      keys = [keys];
    }
    for (var index in networks) {
      if (_.any(keys, function(key) { return networks[index][key] === arg; })) {
        return networks[index];
      }
    }
    return undefined;
  }
  return networkMaps[arg];
}

/**
 * @function
 * @member Networks#add
 * Will add a custom Network
 * @param {Object} data
 * @param {string} data.name - The name of the network
 * @param {string} data.alias - The aliased name of the network
 * @param {Number} data.pubkeyhash - The publickey hash prefix
 * @param {Number} data.privatekey - The privatekey prefix
 * @param {Number} data.scripthash - The scripthash prefix
 * @param {Number} data.xpubkey - The extended public key magic
 * @param {Number} data.xprivkey - The extended private key magic
 * @param {Number} data.networkMagic - The network magic number
 * @param {Number} data.port - The network port
 * @param {Array}  data.dnsSeeds - An array of dns seeds
 * @return Network
 */
function addNetwork(data) {

  var network = new Network();

  JSUtil.defineImmutable(network, {
    name: data.name,
    alias: data.alias,
    pubkeyhash: data.pubkeyhash,
    privatekey: data.privatekey,
    scripthash: data.scripthash,
    xpubkey: data.xpubkey,
    xprivkey: data.xprivkey,
    networkMagic: BufferUtil.integerAsBuffer(data.networkMagic),
    port: data.port,
    dnsSeeds: data.dnsSeeds
  });

  _.each(network, function(value) {
    if (!_.isUndefined(value) && !_.isObject(value)) {
      networkMaps[value] = network;
    }
  });

  networks.push(network);

  return network;

}

/**
 * @function
 * @member Networks#remove
 * Will remove a custom network
 * @param {Network} network
 */
function removeNetwork(network) {
  for (var i = 0; i < networks.length; i++) {
    if (networks[i] === network) {
      networks.splice(i, 1);
    }
  }
  for (var key in networkMaps) {
    if (networkMaps[key] === network) {
      delete networkMaps[key];
    }
  }
}

addNetwork({
  name: 'livenet',
  alias: 'mainnet',
  pubkeyhash: 0x00,
  privatekey: 0x80,
  scripthash: 0x05,
  xpubkey:  0x0488b21e,
  xprivkey: 0x0488ade4,
  networkMagic: 0xf9beb4d9,
  port: 8333,
  dnsSeeds: [
    'seed.bitcoin.sipa.be',
    'dnsseed.bluematt.me',
    'dnsseed.bitcoin.dashjr.org',
    'seed.bitcoinstats.com',
    'seed.bitnodes.io',
    'bitseed.xf2.org'
  ]
});

addNetwork({
  name: 'testnet',
  alias: 'testnet',
  pubkeyhash: 0x6f,
  privatekey: 0xef,
  scripthash: 0xc4,
  xpubkey: 0x043587cf,
  xprivkey: 0x04358394,
  networkMagic: 0x0b110907,
  port: 18333,
  dnsSeeds: [
    'testnet-seed.bitcoin.petertodd.org',
    'testnet-seed.bluematt.me',
    'testnet-seed.alexykot.me',
    'testnet-seed.bitcoin.schildbach.de'
  ],
});

/**
* @instance
* @member Networks#livenet
*/
var livenet = getNetwork('livenet');

/**
* @instance
* @member Networks#testnet
*/
var testnet = getNetwork('testnet');

/**
 * @namespace Networks
 */
module.exports = {
  add: addNetwork,
  remove: removeNetwork,
  defaultNetwork: livenet,
  livenet: livenet,
  mainnet: livenet,
  testnet: testnet,
  get: getNetwork
};

@@ -747,23 +747,16 @@
 tion get
-Network
 (arg, ke
@@ -890,59 +890,25 @@
     
-for (var index in networks) %7B%0A      if (_.any(keys,
+var containsArg =
  fun
@@ -919,16 +919,22 @@
 n(key) %7B
+%0A     
  return 
@@ -962,18 +962,91 @@
 === arg;
- %7D
+%0A    %7D;%0A    for (var index in networks) %7B%0A      if (_.any(keys, containsArg
 )) %7B%0A   
@@ -2967,17 +2967,16 @@
 xpubkey:
- 
  0x0488b
@@ -3602,32 +3602,33 @@
 '%0A  %5D,%0A%7D);%0A%0A/**%0A
+ 
 * @instance%0A* @m
@@ -3615,32 +3615,33 @@
 **%0A * @instance%0A
+ 
 * @member Networ
@@ -3647,24 +3647,25 @@
 rks#livenet%0A
+ 
 */%0Avar liven
@@ -3672,23 +3672,16 @@
 et = get
-Network
 ('livene
@@ -3690,16 +3690,17 @@
 );%0A%0A/**%0A
+ 
 * @insta
@@ -3703,16 +3703,17 @@
 nstance%0A
+ 
 * @membe
@@ -3731,16 +3731,17 @@
 testnet%0A
+ 
 */%0Avar t
@@ -3752,23 +3752,16 @@
 et = get
-Network
 ('testne
@@ -3957,19 +3957,12 @@
 get: get
-Network
 %0A%7D;%0A

refactor networks