/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import { isArray } from '../utils'

/**
 * remove text nodes in the nodes array.
 * @param  {Array} nodes
 * @return {Array} nodes without text nodes.
 */
export function trimTextVNodes (vnodes) {
  if (isArray(vnodes)) {
    return vnodes.filter(vnode => !!vnode.tag)
  }
  return vnodes
}

/**
 * get listeners from on config and v-on binding.
 * v-on binding has a priority over on config.
 * @param {vnode} vnode
 * @param {String} evt: event name.
 */
function getListeners (vnode, evt) {
  const handlers = []
  while (vnode) {
    if (vnode.data && vnode.data.on) {
      const handler = vnode.data.on[evt]
      handler && handlers.push(handler)
    }
    if (vnode.componentOptions && vnode.componentOptions.listeners) {
      const handler = vnode.componentOptions.listeners[evt]
      handler && handlers.push(handler)
    }
    vnode = vnode.parent
  }
  return handlers
}

/**
 * Instead of vue's invoker, this function should check if the binding function
 * has a _weex_hook flag. If there is one, the handler should not be triggered.
 * @param {Array | Function} fns
 */
export function applyFns (fns, ...args) {
  if (Array.isArray(fns)) {
    const cloned = fns.slice()
    const len = cloned.length
    for (let i = 0; i < len; i++) {
      const fn = cloned[i]
      if (fn._weex_hook) {
        continue
      }
      fn.apply(null, args)
    }
  }
  else {
    if (!fns._weex_hook) {
      fns.apply(null, args)
    }
  }
}

/**
 * emit native events to enable v-on.
 * @param {VComponent} context: which one to emit a event on.
 * @param {array | object} events: extra events. You can pass in multiple arguments here.
 */
export function createEventMap (context, ...events) {
  const eventMap = {}
  /**
   * Bind some original type event to your specified type event handler.
   * e.g. bind 'tap' event to 'click' event listener: bindFunc('tap')('click').
   * Or bind certian event with your specified handler: bindFunc('click', someFunction)
   */
  const bindFunc = (originalType) => {
    return listenTo => {
      let handler
      const evtName = originalType || listenTo
      if (typeof listenTo === 'function') {
        handler = listenTo
      }
      else if (typeof listenTo === 'string') {
        handler = function (e) {
          /**
           * use '_triggered' to control actural bubbling (allow original bubbling).
           */
          if (e._triggered) {
            return
          }
          /**
           * trigger the closest parent which has bound event handlers.
           */
          let vm = context
          while (vm) {
            const ons = getListeners(vm._vnode || vm.$vnode, listenTo)
            const len = ons.length
            if (len > 0) {
              let idx = 0
              while (idx < len) {
                const on = ons[idx]
                applyFns(on.fns, e)
                idx++
              }
              // once a parent node (or self node) has triggered the handler, then
              // it stops bubbling immediately, and a '_triggered' object is set.
              e._triggered = {
                el: vm.$el
              }
              return
            }
            vm = vm.$parent
          }
        }
        // flag to distinguish from user-binding listeners.
        handler._weex_hook = true
      }
      if (!eventMap[evtName]) {
        eventMap[evtName] = []
      }
      eventMap[evtName].push(handler)
    }
  }

  /**
   * component's extra event bindings. This is mostly for the needs of component's
   * own special behaviours. These handlers will be processed after the user's
   * corresponding event handlers.
   */
  if (events) {
    const len = events.length
    for (let i = 0; i < len; i++) {
      const extra = events[i]
      if (isArray(extra)) {
        extra.forEach(bindFunc())
      }
      else if (typeof extra === 'object') {
        for (const key in extra) {
          bindFunc(key)(extra[key])
        }
      }
    }
  }

  return eventMap
}
