'use strict';

/**
 * @license
 * Copyright 2016 Leif Olsen. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * A javascript utility for conditionally creating a list of strings.
 * The function takes any number of arguments which can be a string or object.
 * Inspired by (but not copied from) JedWatson/classnames, https://github.com/JedWatson/classnames
 *
 * @param  {*} args the strings and/or objects to
 * @return {Array} a list of strings
 * @example
 * // Returns ['foo', 'bar', 'baz', 'quux']
 * stringList(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
 * @example see the tests for more examples
 */

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.stringList = exports.randomString = exports.joinStrings = undefined;

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

var _keys2 = _interopRequireDefault(_keys);

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

var stringList = function stringList() {
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }

  var isString = function isString(str) {
    return str != null && typeof str === 'string';
  };

  var flatten = function flatten(list) {
    return list.reduce(function (a, b) {
      return a.concat(Array.isArray(b) ? flatten(b) : b);
    }, []);
  };

  var objectToStrings = function objectToStrings(arg) {
    return (0, _keys2.default)(arg).filter(function (key) {
      return arg[key];
    }).map(function (key) {
      return key;
    });
  };

  return args.filter(function (arg) {
    return !!arg;
  }).map(function (arg) {
    return isString(arg) ? arg : objectToStrings(arg);
  }).reduce(function (result, arg) {
    return result.concat(Array.isArray(arg) ? flatten(arg) : arg);
  }, []);
};

/**
 * A simple javascript utility for conditionally joining strings together.
 * The function takes a delimiter string and any number of arguments which can be a string or object.
 *
 * @param delimiter delimiter to separate joined strings
 * @param  {*} args the strings and/or objects to join
 * @return {String} the joined strings
 * @example
 * // Returns 'foo, bar, baz, quux'
 * joinStrings(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
 * @example see the tests for more examples
 */
var joinStrings = function joinStrings() {
  for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
    args[_key2 - 1] = arguments[_key2];
  }

  var delimiter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ' ';
  return stringList.apply(undefined, args).join(delimiter);
};

/**
 * Generates a random string with a given length
 * @param n {Integer} length of generated string
 * @see http://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
 * @return {String} the random string
 * @example
 * // Returns e.g. 'pd781w0y'
 * randomString(8);
 * @example see the tests for more examples
 */
var randomString = function randomString() {
  var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 12;
  return Array(n + 1).join((Math.random().toString(36) + '00000000000000000').slice(2, 18)).slice(0, n);
};

exports.joinStrings = joinStrings;
exports.randomString = randomString;
exports.stringList = stringList;