/*
 * 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 Comment from './Comment'
import Element from './Element'
import Listener from '../bridge/Listener'
import { checkLevel, debugLog } from '../shared/utils'
import { TaskCenter } from '../bridge/TaskCenter'
import { createHandler } from '../bridge/Handler'
import { addDoc, removeDoc, appendBody, setBody } from './operation'

/**
 * Update all changes for an element.
 * @param {object} element
 * @param {object} changes
 */
function updateElement (el, changes) {
  const attrs = changes.attrs || {}
  for (const name in attrs) {
    el.setAttr(name, attrs[name], true)
  }
  const style = changes.style || {}
  for (const name in style) {
    el.setStyle(name, style[name], true)
  }
}

export default class Document {
  constructor (id, url, handler) {
    id = id ? id.toString() : ''
    this.id = id
    this.URL = url

    addDoc(id, this)
    this.nodeMap = {}
    const L = Document.Listener || Listener
    this.listener = new L(id, handler || createHandler(id, Document.handler)) // deprecated
    this.taskCenter = new TaskCenter(id, handler ? (id, ...args) => handler(...args) : Document.handler)
    this.createDocumentElement()
  }

  /**
  * Get the node from nodeMap.
  * @param {string} reference id
  * @return {object} node
  */
  getRef (ref) {
    return this.nodeMap[ref]
  }

  /**
  * Turn on batched updates.
  */
  open () {
    this.listener.batched = false
  }

  /**
  * Turn off batched updates.
  */
  close () {
    this.listener.batched = true
  }

  /**
  * Create the document element.
  * @return {object} documentElement
  */
  createDocumentElement () {
    if (!this.documentElement) {
      const el = new Element('document')
      el.docId = this.id
      el.ownerDocument = this
      el.role = 'documentElement'
      el.depth = 0
      el.ref = '_documentElement'
      this.nodeMap._documentElement = el
      this.documentElement = el

      Object.defineProperty(el, 'appendChild', {
        configurable: true,
        enumerable: true,
        writable: true,
        value: (node) => {
          appendBody(this, node)
        }
      })

      Object.defineProperty(el, 'insertBefore', {
        configurable: true,
        enumerable: true,
        writable: true,
        value: (node, before) => {
          appendBody(this, node, before)
        }
      })

      if (checkLevel('debug')) {
        debugLog(`Create document element (id: "${el.docId}", ref: "${el.ref}")`)
      }
    }

    return this.documentElement
  }

  /**
  * Create the body element.
  * @param {string} type
  * @param {objct} props
  * @return {object} body element
  */
  createBody (type, props) {
    if (!this.body) {
      const el = new Element(type, props)
      setBody(this, el)
      if (checkLevel('debug')) {
        debugLog(`[createBody](${this.id},${el.type},${el.ref}) `
          + `(${JSON.stringify(el.toJSON(true))}).`)
      }
    }

    return this.body
  }

  /**
  * Create an element.
  * @param {string} tagName
  * @param {objct} props
  * @return {object} element
  */
  createElement (tagName, props) {
    const el = new Element(tagName, props)
    if (checkLevel('debug')) {
      debugLog(`[createElement](${this.id},${el.type},${el.ref}) `
        + `(${JSON.stringify(el.toJSON(true))}).`)
    }
    return el
  }

  /**
  * Create an comment.
  * @param {string} text
  * @return {object} comment
  */
  createComment (text) {
    return new Comment(text)
  }

  /**
  * Fire an event on specified element manually.
  * @param {object} element
  * @param {string} event type
  * @param {object} event object
  * @param {object} dom changes
  * @param {object} options
  * @return {} anything returned by handler function
  */
  fireEvent (el, type, event, domChanges, options) {
    if (!el) {
      return
    }
    event = event || {}
    event.type = event.type || type
    event.target = el
    event.currentTarget = el
    event.timestamp = Date.now()
    if (domChanges) {
      updateElement(el, domChanges)
    }
    let isBubble
    const $root = this.getRef('_root')
    if ($root && $root.attr) {
      isBubble = $root.attr['bubble'] === 'true'
    }
    return el.fireEvent(type, event, isBubble, options)
  }

  /**
  * Destroy current document, and remove itself form docMap.
  */
  destroy () {
    if (checkLevel('debug')) {
      debugLog(`[destroy](${this.id},document,${this.ref}) `
        + `Destroy document (id: "${this.id}", URL: "${this.URL}")`)
    }
    this.taskCenter.destroyCallback()
    delete this.listener
    delete this.nodeMap
    delete this.taskCenter
    removeDoc(this.id)
  }
}

// default task handler
Document.handler = null
