'use strict';

(function () {
  // import Objects
  var BlackListIdentifier = exports.blackListIdentifier, 
  EightDigitsWithDddIdentifier = exports.eightDigitsWithDddIdentifier,
  EightDigitsWithoutDddIdentifier = exports.eightDigitsWithoutDddIdentifier,
  NineDigitsWithDddIdentifier = exports.nineDigitsWithDddIdentifier,
  NineDigitsWithoutDddIdentifier = exports.nineDigitsWithoutDddIdentifier,
  ZeroDddEightDigitsIdentifier = exports.zeroDddEightDigitsIdentifier,
  ZeroDddNineDigitsIdentifier = exports.zeroDddNineDigitsIdentifier,
  CspDddEightDigitsIdentifier = exports.cspDddEightDigitsIdentifier,
  ZeroCspDddEightDigitsIdentifier = exports.zeroCspDddEightDigitsIdentifier,
  CspDddNineDigitsIdentifier = exports.cspDddNineDigitsIdentifier,
  ZeroCspDddNineDigitsIdentifier = exports.zeroCspDddNineDigitsIdentifier,
  ZeroZeroCcNumberIdentifier = exports.zeroZeroCcNumberIdentifier,
  ZeroZeroCsCcNumberIdentifier = exports.zeroZeroCsCcNumberIdentifier,
  LastIdentifier = exports.lastIdentifier,
  // code
  map;

  exports.converterFactory = {
    convert: function (ddd, phone) {
      phone = phone.replace(/\s/g, '');
      var formattedPhone = phone.replace(/([()-])/g, ''),
      convert = findConvert(formattedPhone);

      if (convert) {
        return convert(ddd, formattedPhone);
      }
      return '';
    }
  };

  map = {
    eightDigitsWithDdd: exports.eightDigitsWithDddConverter,
    eightDigitsWithoutDdd: exports.eightDigitsWithoutDddConverter,
    nineDigitsWithDdd: exports.nineDigitsWithDddConverter,
    nineDigitsWithoutDdd: exports.nineDigitsWithoutDddConverter,
    zeroDddEightDigits: exports.zeroDddEightDigitsConverter,
    zeroDddNineDigits: exports.zeroDddNineDigitsConverter,
    cspDddEightDigits: exports.cspDddEightDigitsConverter,
    zeroCspDddEightDigits: exports.zeroCspDddEightDigitsConverter,
    cspDddNineDigits: exports.cspDddNineDigitsConverter,
    zeroCspDddNineDigits: exports.zeroCspDddNineDigitsConverter,
    zeroZeroCcNumber: exports.zeroZeroCcNumberConverter,
    zeroZeroCsCcNumber: exports.zeroZeroCsCcNumberConverter
  };

  function findConvert(phone) {
    var blackList = new BlackListIdentifier(),
    eightDigitsWithDdd = new EightDigitsWithDddIdentifier(),
    eightDigitsWithoutDdd = new EightDigitsWithoutDddIdentifier(),
    nineDigitsWithDdd = new NineDigitsWithDddIdentifier(),
    nineDigitsWithoutDdd = new NineDigitsWithoutDddIdentifier(),
    zeroDddEightDigits = new ZeroDddEightDigitsIdentifier(),
    zeroDddNineDigits = new ZeroDddNineDigitsIdentifier(),
    cspDddEightDigits = new CspDddEightDigitsIdentifier(),
    zeroCspDddEightDigits = new ZeroCspDddEightDigitsIdentifier(),
    cspDddNineDigits = new CspDddNineDigitsIdentifier(),
    zeroCspDddNineDigits = new ZeroCspDddNineDigitsIdentifier(),
    zeroZeroCcNumber = new ZeroZeroCcNumberIdentifier(),
    zeroZeroCsCcNumber = new ZeroZeroCsCcNumberIdentifier(),
    last = new LastIdentifier();
    blackList.setNext(eightDigitsWithDdd);
    eightDigitsWithDdd.setNext(eightDigitsWithoutDdd);
    eightDigitsWithoutDdd.setNext(nineDigitsWithDdd);
    nineDigitsWithDdd.setNext(nineDigitsWithoutDdd);
    nineDigitsWithoutDdd.setNext(zeroDddEightDigits);
    zeroDddEightDigits.setNext(zeroDddNineDigits);
    zeroDddNineDigits.setNext(cspDddEightDigits);
    cspDddEightDigits.setNext(zeroCspDddEightDigits);
    zeroCspDddEightDigits.setNext(cspDddNineDigits);
    cspDddNineDigits.setNext(zeroCspDddNineDigits);
    zeroCspDddNineDigits.setNext(zeroZeroCcNumber);
    zeroZeroCcNumber.setNext(zeroZeroCsCcNumber);
    zeroZeroCsCcNumber.setNext(last);
    
    return map[blackList.identify(phone)];
  }
}());
