'use strict';

var _keys = require('babel-runtime/core-js/object/keys');

var _keys2 = _interopRequireDefault(_keys);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// Adapted from https://github.com/hughsk/flat

var isBuffer = require('is-buffer');

module.exports = flatten;
flatten.flatten = flatten;
flatten.unflatten = unflatten;

function flatten(target, opts) {
  opts = opts || {};

  var delimiter = opts.delimiter || '.';
  var maxDepth = opts.maxDepth;
  var output = {};

  function step(object, prev, currentDepth) {
    currentDepth = currentDepth || 1;
    (0, _keys2.default)(object).forEach(function (key) {
      var value = object[key];
      // We want to preserve arrays of strings and numbers, but flatten arrays of objects
      var isarray = opts.safe && Array.isArray(value) && Object.prototype.toString.call(value[0]) !== '[object Object]';
      var type = Object.prototype.toString.call(value);
      var isbuffer = isBuffer(value);
      var isobject = type === '[object Object]' || type === '[object Array]';

      var newKey = prev ? prev + delimiter + key : key;

      if (!isarray && !isbuffer && isobject && (0, _keys2.default)(value).length && (!opts.maxDepth || currentDepth < maxDepth)) {
        return step(value, newKey, currentDepth + 1);
      }

      // Remove any empty objects
      output[newKey] = value;
    });
  }

  step(target);

  return output;
}

function unflatten(target, opts) {
  opts = opts || {};

  var delimiter = opts.delimiter || '.';
  var overwrite = opts.overwrite || false;
  var result = {};

  var isbuffer = isBuffer(target);
  if (isbuffer || Object.prototype.toString.call(target) !== '[object Object]') {
    return target;
  }

  // safely ensure that the key is
  // an integer.
  function getkey(key) {
    var parsedKey = Number(key);

    return isNaN(parsedKey) || key.indexOf('.') !== -1 || opts.object ? key : parsedKey;
  }

  var sortedKeys = (0, _keys2.default)(target).sort(function (keyA, keyB) {
    return keyA.length - keyB.length;
  });

  sortedKeys.forEach(function (key) {
    var split = key.split(delimiter);
    var key1 = getkey(split.shift());
    var key2 = getkey(split[0]);
    var recipient = result;

    while (key2 !== undefined) {
      var type = Object.prototype.toString.call(recipient[key1]);
      var isobject = type === '[object Object]' || type === '[object Array]';

      // do not write over falsey, non-undefined values if overwrite is false
      if (!overwrite && !isobject && typeof recipient[key1] !== 'undefined') {
        return;
      }

      if (overwrite && !isobject || !overwrite && recipient[key1] == null) {
        recipient[key1] = typeof key2 === 'number' && !opts.object ? [] : {};
      }

      recipient = recipient[key1];
      if (split.length > 0) {
        key1 = getkey(split.shift());
        key2 = getkey(split[0]);
      }
    }

    // unflatten again for 'messy objects'
    recipient[key1] = unflatten(target[key], opts);
  });

  return result;
}
//# sourceMappingURL=flat.js.map