/**
 * Deep-copy an object.
 * @param {Object} obj - The object to clone.
 * @return {Object} The cloned object.
 */
export function clone (obj) {
  return JSON.parse(JSON.stringify(obj))
}

/**
 * Dispatch a custom JavaScript event.
 * @param {HTMLElement} el DOM element to dispatch the event on.
 * @param {string} type Event name.
 */
export function dispatch (el, type) {
  const e = document.createEvent('Event')
  e.initEvent(type, true, true)
  el.dispatchEvent(e)
}

/**
 * Escape characters that have a meaning in regular expressions.
 * @param {string} str - The string to process.
 * @return {string} The string with escaped special characters.
 */
export function escapeRegExp (str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') // eslint-disable-line no-useless-escape
}

/**
 * Comply to RFC 3986 when encoding URI components.
 * Encode also !, ', (, ) and *.
 * @param {string} str - The URI component to encode.
 * @return {string} The encoded URI component.
 */
export function fixedEncodeURIComponent (str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16))
}

/**
 * Validate a destination property’s value.
 * Valid values are absolute or relative urls or expressions starting with `node/`.
 * @param {string} destination - The expression to validate.
 * @return {boolean} Is it valid?
 */
export function validateDestination (destination) {
  return (destination.length &&
    destination.match(/^(www\.|http:\/\/|https:\/\/|\/)/) &&
    destination.indexOf(' ') === -1) ||
    destination.match(/^node\//)
}

export default {
  clone,
  dispatch,
  validateDestination
}
