<script>
class DOMAgent {
  constructor(delegate) {
    this.enabled = false;
    this.delegate_ = delegate;
    this.nextNodeId_ = 1;
    this.nodeToId_ = new Map();
    this.idToNode_ = new Map();
    this.observer_ = null;
    Object.preventExtensions(this);
  }

  getIdForNode_(node) {
    if (this.nodeToId_.has(node))
      return this.nodeToId_.get(node);
    var id = this.nextNodeId_++;
    this.nodeToId_.set(node, id);
    this.idToNode_.set(id, node);
    return id;
  }

  getNodeForId(nodeId) {
    return this.idToNode_.get(nodeId);
  }

  serializeChildren_(node) {
    var children = [];
    for (var child = node.firstChild; child; child = child.nextSibling) {
      var record = this.serializeNode_(child);
      if (record)
        children.push(record);
    }
    return children;
  }

  serializeAttributes_(element) {
    var attributes = [];
    var attrs = element.getAttributes();
    for (var i = 0; i < attrs.length; ++i) {
      var attr = attrs[i];
      attributes.push(attr.name);
      attributes.push(attr.value);
    }
    return attributes;
  }

  serializeNode_(node) {
    var id = this.getIdForNode_(node);

    var record = {
      nodeId: id,
    };

    var isContainer = false;

    if (node instanceof Element) {
      isContainer = true;
      record.nodeType = 1;
      record.nodeName = node.tagName;
      record.localName = node.tagName;
      record.nodeValue = "";
      record.attributes = this.serializeAttributes_(node);
    } else if (node instanceof Text) {
      record.nodeType = 3;
      record.nodeName = "#text";
      var nodeValue = node.data;
      if (!nodeValue.trim())
        return null;
      record.nodeValue = nodeValue;
    } else if (node instanceof Document) {
      isContainer = true;
      record.nodeType = 9;
      record.nodeName = "#document";
      record.localName = "";
      record.nodeValue = "";
      record.documentURL = node.URL;
      record.baseURL = node.baseURI;
    } else if (node instanceof DocumentFragment) {
      isContainer = true;
      record.nodeType = 11;
      record.nodeName = "#document-fragment";
      record.localName = "";
      record.nodeValue = "";
    } else {
      console.log("Unknown node type");
      return null;
    }

    if (isContainer) {
      var children = this.serializeChildren_(node);
      if (children.length) {
        record.childNodeCount = children.length;
        record.children = children;
      }
    }

    return record;
  }

  enable() {
    this.enabled = true;
    this.observer_ = new MutationObserver(this.mutationCallback_.bind(this));
    this.observer_.observe(document, {
      childList: true,
      attributes: true,
      characterData: true,
      subtree : true,
    });
  }

  getDocument() {
    return {
      root: this.serializeNode_(document),
    };
  }

  hideHighlight() {
  }

  highlightNode() {
  }

  mutationCallback_(mutationRecords) {
    for (var i = 0; i < mutationRecords.length; ++i) {
      var record = mutationRecords[i];
      var type = record.type;
      var target = record.target;
      var nodeId = this.getIdForNode_(target);
      if (type == "attributes") {
        var attributeName = record.attributeName;
        if (target.hasAttribute(attributeName)) {
          this.delegate_.sendMessage("DOM.attributeModified", {
            nodeId: nodeId,
            name: attributeName,
            value: target.getAttribute(attributeName),
          });
        } else {
          this.delegate_.sendMessage("DOM.attributeRemoved", {
            nodeId: nodeId,
            name: attributeName,
          });
        }
      } else if (type == "characterData") {
        this.delegate_.sendMessage("DOM.characterDataModified", {
          nodeId: nodeId,
          characterData: target.data,
        });
      } else if (type == "childList") {
        // FIXME: If this subtree isn't expanded, we only need to send across the
        // {"method":"DOM.childNodeCountUpdated","params":"nodeId":648,"childNodeCount":2}

        Array.prototype.forEach.call(record.removedNodes, function(node) {
          this.delegate_.sendMessage("DOM.childNodeRemoved", {
            parentNodeId: nodeId,
            nodeId: this.getIdForNode_(node),
          });
        }.bind(this));

        Array.prototype.forEach.call(record.addedNodes, function(node) {
          var previousNodeId = node.previousSibling ? this.getIdForNode_(node.previousSibling) : 0;
          this.delegate_.sendMessage("DOM.childNodeInserted", {
            parentNodeId: nodeId,
            previousNodeId: previousNodeId,
            node: this.serializeNode_(node),
          });
        }.bind(this));
      }
    }
  }
}

module.exports = DOMAgent;
</script>
