'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

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

var units = ['y', 'M', 'w', 'd', 'h', 'm', 's', 'ms'];
var unitsAsc = _lodash2.default.sortBy(units, function (unit) {
  return _moment2.default.duration(1, unit).valueOf();
});
var unitsDesc = unitsAsc.reverse();

/* This is a simplified version of elasticsearch's date parser */
function parse(text, roundUp) {
  if (!text) return undefined;
  if (_moment2.default.isMoment(text)) return text;
  if (_lodash2.default.isDate(text)) return (0, _moment2.default)(text);

  var time = void 0;
  var mathString = '';
  var index = void 0;
  var parseString = void 0;

  if (text.substring(0, 3) === 'now') {
    time = (0, _moment2.default)();
    mathString = text.substring('now'.length);
  } else {
    index = text.indexOf('||');
    if (index === -1) {
      parseString = text;
      mathString = ''; // nothing else
    } else {
        parseString = text.substring(0, index);
        mathString = text.substring(index + 2);
      }
    // We're going to just require ISO8601 timestamps, k?
    time = (0, _moment2.default)(parseString);
  }

  if (!mathString.length) {
    return time;
  }

  return parseDateMath(mathString, time, roundUp);
}

function parseDateMath(mathString, time, roundUp) {
  var dateTime = time;
  var len = mathString.length;
  var i = 0;

  while (i < len) {
    var c = mathString.charAt(i++);
    var type = void 0;
    var num = void 0;
    var unit = void 0;

    if (c === '/') {
      type = 0;
    } else if (c === '+') {
      type = 1;
    } else if (c === '-') {
      type = 2;
    } else {
      return;
    }

    if (isNaN(mathString.charAt(i))) {
      num = 1;
    } else if (mathString.length === 2) {
      num = mathString.charAt(i);
    } else {
      var numFrom = i;
      while (!isNaN(mathString.charAt(i))) {
        i++;
        if (i > 10) return;
      }
      num = parseInt(mathString.substring(numFrom, i), 10);
    }

    if (type === 0) {
      // rounding is only allowed on whole, single, units (eg M or 1M, not 0.5M or 2M)
      if (num !== 1) {
        return;
      }
    }

    unit = mathString.charAt(i++);

    // append additional characters in the unit
    for (var j = i; j < len; j++) {
      var unitChar = mathString.charAt(i);
      if (/[a-z]/i.test(unitChar)) {
        unit += unitChar;
        i++;
      } else break;
    }

    if (!_lodash2.default.contains(units, unit)) {
      return;
    } else {
      if (type === 0) {
        if (roundUp) dateTime.endOf(unit);else dateTime.startOf(unit);
      } else if (type === 1) {
        dateTime.add(num, unit);
      } else if (type === 2) {
        dateTime.subtract(num, unit);
      }
    }
  }

  return dateTime;
}

exports.default = {
  parse: parse,
  units: Object.freeze(units),
  unitsAsc: Object.freeze(unitsAsc),
  unitsDesc: Object.freeze(unitsDesc)
};
module.exports = exports['default'];