/**
 * Configure Rowdy.
 *
 * Override options with:
 * ```
 * ROWDY_OPTIONS='{ clientLogger: true }'
 * ```
 *
 * Hook to a configuration with:
 * ```
 * ROWDY_SETTINGS="local.chrome"
 * ```
 *
 * Basic configurations for a Browser `settings` entry:
 * ```
 * {
 *   // Selenium Desired Capabilities.
 *   // https://code.google.com/p/selenium/wiki/DesiredCapabilities
 *   desiredCapabilities: {},
 *
 *   // WD.js remote parameters.
 *   // https://github.com/admc/wd#named-parameters
 *   remote: {},
 *
 *   // Uses SauceLabs SAAS.
 *   isSauceLabs: true,
 *
 *   // Uses BrowserStack SAAS.
 *   isBrowserStack: true,
 * }
 * ```
 */
var _ = require("lodash");

var ROWDY_SETTINGS = process.env.ROWDY_SETTINGS || "";
var ROWDY_OPTIONS = process.env.ROWDY_OPTIONS || "{}";
var QUOTES_RE = /^[\s\\\'\"]*|[\s\\\'\"]*$/g;

/**
 * Global default: local phantomjs.
 *
 * Note: Only if *no* default top-level setting specified.
 */
var GLOBAL_DEFAULT = {
  desiredCapabilities: {
    browserName: "phantomjs"
  },
  server: {
    start: true,
    phantomPath: false
  }
};

var DEFAULTS = {
  /**
   * Misc. options.
   *
   * Options can be globally overriden with a merge of a stringified JSON
   * object like:
   * ```
   * ROWDY_OPTIONS='{ "clientLogger": true, "serverLogger": true }'
   * ```
   */
  options: {
    clientLogger: false,
    serverLogger: false,
    serverDebug: false
  },

  settings: {}
};

// TODO: Refactor and decompose out the `max-statements` warning.
/*eslint-disable max-statements*/
module.exports = function (cfg) {
  // Merge config.
  cfg = _.cloneDeep(_.merge({}, DEFAULTS, cfg));

  // Merge options.
  try {
    _.merge(cfg.options, JSON.parse(ROWDY_OPTIONS.replace(QUOTES_RE, "")));
  } catch (err) {
    /*eslint-disable no-console*/
    console.error("Unable to parse ROWDY_OPTIONS: " + err.toString());
    /*eslint-enable no-console*/
    throw err;
  }

  // Add default setting if not set.
  if (!cfg.settings.default) {
    cfg.settings.default = GLOBAL_DEFAULT;
  }

  // Then, apply merge settings defaults to other objects one level down.
  _.each(cfg.settings, function (objs, objsKey) {
    if (objsKey === "default" && !objs.default) { return; }
    _.each(objs, function (obj, objKey) {
      if (objKey === "default" || !_.isObject(obj)) { return; }
      // Merge defaults
      objs[objKey] = _.merge({}, objs.default, obj);
    });
  });

  // Finally, choose desired configuration and place on `setting`.
  var settingsPath = ROWDY_SETTINGS.replace(QUOTES_RE, "").split(".");
  settingsPath = _.chain(settingsPath)
    .map(function (v) { return v.trim(); })
    .filter(_.identity)
    .value();

  // If no settings path, _try_ to go for `local.default`, then `default`.
  if (!settingsPath.length) {
    if (cfg.settings.local && cfg.settings.local.default) {
      settingsPath = ["local", "default"];
    } else {
      settingsPath = ["default"];
    }
  }

  cfg.setting = _.reduce(settingsPath, function (memo, key) {
    if (!_.has(memo, key)) {
      throw new Error("Bad ROWDY_SETTINGS path: " + ROWDY_SETTINGS);
    }

    return memo[key];
  }, cfg.settings);

  return cfg;
};
/*eslint-enable max-statements*/

@@ -817,16 +817,222 @@
 %5D*$/g;%0A%0A
+/**%0A * Driver libraries.%0A *%0A * Map enum to %60require%60 statement.%0A */%0Avar DRIVER_LIBS = %7B%0A  WD: %22wd%22,                   // https://github.com/admc/wd%0A  WEBDRIVERIO: %22webdriverio%22  // http://webdriver.io/%0A%7D;%0A%0A
 /**%0A * G
@@ -1063,16 +1063,16 @@
 ntomjs.%0A
-
  *%0A * No
@@ -1584,24 +1584,80 @@
 Debug: false
+,%0A    driverLib: DRIVER_LIBS.WD // %60wd%60 or %60webdriverio%60
 %0A  %7D,%0A%0A  set
@@ -1882,22 +1882,197 @@
  // 
-Merge options.
+--------------------------------------------------------------------------%0A  // Options: Rowdy configuration.%0A  // --------------------------------------------------------------------------
 %0A  t
@@ -2337,39 +2337,381 @@
  // 
-Add default setting if not set.
+Validate driver library.%0A  if (!_.includes(DRIVER_LIBS, cfg.options.driverLib)) %7B%0A    throw new Error(%22Unknown driver library option: %22 + cfg.options.driverLib);%0A  %7D%0A%0A  // --------------------------------------------------------------------------%0A  // Settings: Available Selenium-ish options.%0A  // --------------------------------------------------------------------------
 %0A  i
@@ -3694,16 +3694,230 @@
  %7D%0A  %7D%0A%0A
+  // --------------------------------------------------------------------------%0A  // Setting: The actual chosen Selenium-ish setting.%0A  // --------------------------------------------------------------------------%0A
   cfg.se

Add configuration for chosen library.