/*
 * 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 {
  camelizeKeys,
  // hyphenateKeys,
  extend,
  extendTruthy,
  trimComment,
  normalizeStyle,
  autoPrefix,
  isArray,
  getParentScroller,
  supportSticky,
  appendCss
} from '../utils'
import { tagBegin, tagEnd } from '../utils/perf'
/* istanbul ignore next */

let pseudoId = 0
/**
 * get scoped class style map from stylesheets in <head>.
 */
export function getHeadStyleMap () {
  if (process.env.NODE_ENV === 'development') {
    tagBegin('getHeadStyleMap')
  }
  const needToRemoveStyleSheetNodes = []
  const styleSheetsArr = Array.from(document.styleSheets || []).filter(function (styleSheet) {
    return styleSheet.ownerNode.getAttribute('weex-scanned') !== '1'
  })

  const res = Array.from(styleSheetsArr)
    .reduce((pre, styleSheet) => {
      styleSheet.ownerNode.setAttribute('weex-scanned', 1)
      /**
       * why not using styleSheet.rules || styleSheet.cssRules to get css rules ?
       * because weex's components defined non-standard style attributes, which is
       * auto ignored when access rule.cssText.
       * another reason not to use cssRules directy:
       * @issue: https://stackoverflow.com/questions/21642277/security-error-the-operation-is-insecure-in-firefox-document-stylesheets
       */
      if (
        // css in a link. just ignore this. probably a link stylesheet.
        (styleSheet.ownerNode.tagName.toLowerCase() === 'link')
        || !styleSheet.ownerNode.textContent
        // pseudo class styleSheet node is generated by weex. just ignore it.
        || styleSheet.ownerNode.id.match(/weex-pseudo-\d+/)) {
        return pre
      }
      /**
       * start to analyze it's content.
       */
      const strArr = trimComment(styleSheet.ownerNode.textContent.trim()).split(/}/)
      const len = strArr.length
      const rules = []
      for (let i = 0; i < len; i++) {
        const str = strArr[i]
        if (!str || str.match(/^\s*$/)) {
          continue
        }
        /**
         * should match these cases:
         * .a[data-v-xxx] { color: red; }
         * .a[data-v-xxx]:active { color: green; }
         * .a[data-v-xxx], .b[data-v-xxx] { color: red; }
         *
         * should not match these cases:
         * .a { color: red; }
         * etc.
         */
        const match = str.match(/((?:,?\s*\.[\w-]+\[data-v-\w+\](?::\w+)?)+)\s*({[^}]+)/)
        if (!match) {
          // not the vue static class styles map. so acquire no rules for this styleSheet.
          // just jump through this styleSheet and go to analyzing next.
          return pre
        }
        const clsNms = match[1].split(',').map(n => n.trim())
        const cssText = match[2].replace(/[{}]/g, '').trim()
        let clsNmsIdx = 0
        const clsNmsLen = clsNms.length
        while (clsNmsIdx < clsNmsLen) {
          rules.push({
            selectorText: clsNms[clsNmsIdx],
            cssText
          })
          clsNmsIdx++
        }
      }
      Array.from(rules).forEach(rule => {
        const selector = rule.selectorText || ''
        let isPseudo = false
        if (selector.match(/:(?:active|focus|enabled|disabled)/)) {
          isPseudo = true
        }
        const styleObj = trimComment(rule.cssText).split(';')
          .reduce((styleObj, statement) => {
            statement = statement.trim()
            if (statement && statement.indexOf('/*') <= -1) {
              const resArr = statement.split(':').map((part) => part.trim())
              styleObj[resArr[0]] = resArr[1]
            }
            return styleObj
          }, {})
        if (isPseudo) {
          const txt = Object.keys(styleObj).reduce(function (pre, cur) {
            return pre + `${cur}:${styleObj[cur]}!important;`
          }, '')
          appendCss(`${selector}{${txt}}`, `weex-pseudo-${pseudoId++}`)
        }
        const objMap = !isPseudo ? pre : pre.pseudo
        const res = objMap[selector]
        if (!res) {
          objMap[selector] = styleObj
        }
        else {
          extend(objMap[selector], styleObj)
        }
      })
      /**
       * remove this styleSheet node since it's in the styleMap already. And this style
       * should only be fetched and used from styleMap to generate the final combined
       * component style, not from the stylesheet itself.
       */
      needToRemoveStyleSheetNodes.push(styleSheet.ownerNode)
      return pre
    }, { pseudo: {}})
  if (!window._no_remove_style_sheets) {
    needToRemoveStyleSheetNodes.forEach(function (node) {
      node.parentNode.removeChild(node)
    })
  }
  else if (process.env.NODE_ENV === 'development') {
    console.warn(`[vue-render] you've defined '_no_remove_style_sheets' and the v-data-xx stylesheets will not be removed.`)
  }
  if (process.env.NODE_ENV === 'development') {
    tagEnd('getHeadStyleMap')
  }
  return res
}

// export function getScopeIds (context) {
//   const arr = []
//   let ctx = context
//   let scopeId
//   while (ctx) {
//     scopeId = ctx.$options._scopeId
//     scopeId && arr.push(scopeId)
//     ctx = ctx.$options.parent
//   }
//   return arr
// }

export function getScopeId (vnode) {
  return vnode.context.$options._scopeId
}

/**
 * get style in <style scoped> tags for this component.
 */
export function getScopeStyle (vnode, classNames) {
  const scopeId = getScopeId(vnode)
  const style = {}
  const styleMap = weex._styleMap || {}
  let clsNmsIdx = 0
  const clsNmsLen = classNames.length
  while (clsNmsIdx < clsNmsLen) {
    const cls = `.${classNames[clsNmsIdx]}[${scopeId}]`
    const map = styleMap[cls]
    map && extendTruthy(style, map)
    clsNmsIdx++
  }
  return camelizeKeys(style)
}

function getStyle (vnode, extract) {
  const data = vnode.data || {}
  const staticClassNames = (typeof data.staticClass === 'string') ? data.staticClass.split(' ') : (data.staticClass || [])
  const classNames = (typeof data.class === 'string') ? data.class.split(' ') : (data.class || [])
  const clsNms = staticClassNames.concat(classNames)
  const style = normalizeStyle(getScopeStyle(vnode, clsNms))
  /**
   * cache static style and bind style.
   * cached staticStyle (including style and staticStyle) has already been normalized
   * in $processStyle. So there's no need to normalize it again.
   */
  if (!data.cached) {
    // cache staticStyle once in the beginning.
    data.cached = extendTruthy({}, data.staticStyle)
  }
  // cache binding style every time since the binding style is variable.
  extendTruthy(data.cached, data.style)
  extend(style, data.cached)
  data.staticStyle = style
  if (extract) {
    delete data.staticStyle
    delete data.style
  }
  return style
}

/**
 * get style merged with static styles, binding styles, and scoped class styles,
 * with keys in camelcase.
 */
export function getComponentStyle (context, extract) {
  if (!context.$vnode) {
    if (process.env.NODE_ENV === 'development') {
      return console.error('[vue-render] getComponentStyle failed: no $vnode in context.')
    }
    return {}
  }
  let style = {}
  let vnode = context.$vnode
  while (vnode) {
    extend(style, getStyle(vnode, extract))
    vnode = vnode.parent
  }
  style = autoPrefix(style)
  /**
   * when prefixed value is a array, it should be applied to element
   * during the next tick.
   * e.g.
   *  background-image:  linear-gradient(to top,#f5fefd,#ffffff);
   *  will generate:
   *  {
   *    backgroundImage: [
   *      "-webkit-linear-gradient(to top,#f5fefd,#ffffff)",
   *      "-moz-linear-gradient(to top,#f5fefd,#ffffff)",
   *      "linear-gradient(to top,#f5fefd,#ffffff)"]
   *  }
   */
  for (const k in style) {
    if (Array.isArray(style[k])) {
      const vals = style[k]
      context.$nextTick(function () {
        const el = context.$el
        if (el) {
          for (let i = 0; i < vals.length; i++) {
            el.style[k] = vals[i]
          }
        }
      })
      if (k !== 'position') { delete style[k] }
    }
  }

  /**
   * If position is 'sticky', then add it to the stickyChildren of the parent scroller.
   */
  const pos = style.position
  const reg = /sticky$/
  if (pos === 'fixed') {
    context.$nextTick(function () {
      const el = context.$el
      if (el) {
        el.classList.add('weex-fixed')
      }
    })
  }
  else if (isArray(pos) && pos[0].match(reg) || (pos + '').match(reg)) {
    delete style.position
    // use native sticky.
    if (supportSticky()) {
      context.$nextTick(function () {
        const el = context.$el
        if (el) {
          el.classList.add('weex-ios-sticky')
        }
      })
    }
    // use re-implementation of sticky.
    else if (!context._stickyAdded) {
      const uid = context._uid
      const scroller = getParentScroller(context)
      if (scroller) {
        context._stickyAdded = true
        if (!scroller._stickyChildren) {
          scroller._stickyChildren = {}
        }
        scroller._stickyChildren[uid] = context
      }
      context.$nextTick(function () {
        const el = context.$el
        if (el) {
          context._initOffsetTop = el.offsetTop
        }
      })
    }
  }

  return style
}

export function extractComponentStyle (context) {
  return getComponentStyle(context, true)
}

