import { __require as requireWarning } from '../../../../fbjs@2.0.0/node_modules/fbjs/lib/warning.js';

var DraftTreeInvariants_1;
var hasRequiredDraftTreeInvariants;

function requireDraftTreeInvariants () {
	if (hasRequiredDraftTreeInvariants) return DraftTreeInvariants_1;
	hasRequiredDraftTreeInvariants = 1;

	/**
	 * Copyright (c) Facebook, Inc. and its affiliates.
	 *
	 * This source code is licensed under the MIT license found in the
	 * LICENSE file in the root directory of this source tree.
	 *
	 * @format
	 * 
	 * @emails oncall+draft_js
	 *
	 * This is unstable and not part of the public API and should not be used by
	 * production systems. This file may be update/removed without notice.
	 */
	var warning = requireWarning();

	var DraftTreeInvariants = {
	  /**
	   * Check if the block is valid
	   */
	  isValidBlock: function isValidBlock(block, blockMap) {
	    var key = block.getKey(); // is its parent's child

	    var parentKey = block.getParentKey();

	    if (parentKey != null) {
	      var parent = blockMap.get(parentKey);

	      if (!parent.getChildKeys().includes(key)) {
	        process.env.NODE_ENV !== "production" ? warning(true, 'Tree is missing parent -> child pointer on %s', key) : void 0;
	        return false;
	      }
	    } // is its children's parent


	    var children = block.getChildKeys().map(function (k) {
	      return blockMap.get(k);
	    });

	    if (!children.every(function (c) {
	      return c.getParentKey() === key;
	    })) {
	      process.env.NODE_ENV !== "production" ? warning(true, 'Tree is missing child -> parent pointer on %s', key) : void 0;
	      return false;
	    } // is its previous sibling's next sibling


	    var prevSiblingKey = block.getPrevSiblingKey();

	    if (prevSiblingKey != null) {
	      var prevSibling = blockMap.get(prevSiblingKey);

	      if (prevSibling.getNextSiblingKey() !== key) {
	        process.env.NODE_ENV !== "production" ? warning(true, "Tree is missing nextSibling pointer on %s's prevSibling", key) : void 0;
	        return false;
	      }
	    } // is its next sibling's previous sibling


	    var nextSiblingKey = block.getNextSiblingKey();

	    if (nextSiblingKey != null) {
	      var nextSibling = blockMap.get(nextSiblingKey);

	      if (nextSibling.getPrevSiblingKey() !== key) {
	        process.env.NODE_ENV !== "production" ? warning(true, "Tree is missing prevSibling pointer on %s's nextSibling", key) : void 0;
	        return false;
	      }
	    } // no 2-node cycles


	    if (nextSiblingKey !== null && prevSiblingKey !== null) {
	      if (prevSiblingKey === nextSiblingKey) {
	        process.env.NODE_ENV !== "production" ? warning(true, 'Tree has a two-node cycle at %s', key) : void 0;
	        return false;
	      }
	    } // if it's a leaf node, it has text but no children


	    if (block.text != '') {
	      if (block.getChildKeys().size > 0) {
	        process.env.NODE_ENV !== "production" ? warning(true, 'Leaf node %s has children', key) : void 0;
	        return false;
	      }
	    }

	    return true;
	  },

	  /**
	   * Checks that this is a connected tree on all the blocks
	   * starting from the first block, traversing nextSibling and child pointers
	   * should be a tree (preorder traversal - parent, then children)
	   * num of connected node === number of blocks
	   */
	  isConnectedTree: function isConnectedTree(blockMap) {
	    // exactly one node has no previous sibling + no parent
	    var eligibleFirstNodes = blockMap.toArray().filter(function (block) {
	      return block.getParentKey() == null && block.getPrevSiblingKey() == null;
	    });

	    if (eligibleFirstNodes.length !== 1) {
	      process.env.NODE_ENV !== "production" ? warning(true, 'Tree is not connected. More or less than one first node') : void 0;
	      return false;
	    }

	    var firstNode = eligibleFirstNodes.shift();
	    var nodesSeen = 0;
	    var currentKey = firstNode.getKey();
	    var visitedStack = [];

	    while (currentKey != null) {
	      var currentNode = blockMap.get(currentKey);
	      var childKeys = currentNode.getChildKeys();
	      var nextSiblingKey = currentNode.getNextSiblingKey(); // if the node has children, add parent's next sibling to stack and go to children

	      if (childKeys.size > 0) {
	        if (nextSiblingKey != null) {
	          visitedStack.unshift(nextSiblingKey);
	        }

	        var children = childKeys.map(function (k) {
	          return blockMap.get(k);
	        });

	        var _firstNode = children.find(function (block) {
	          return block.getPrevSiblingKey() == null;
	        });

	        if (_firstNode == null) {
	          process.env.NODE_ENV !== "production" ? warning(true, '%s has no first child', currentKey) : void 0;
	          return false;
	        }

	        currentKey = _firstNode.getKey(); // TODO(T32490138): Deal with multi-node cycles here
	      } else {
	        if (currentNode.getNextSiblingKey() != null) {
	          currentKey = currentNode.getNextSiblingKey();
	        } else {
	          currentKey = visitedStack.shift();
	        }
	      }

	      nodesSeen++;
	    }

	    if (nodesSeen !== blockMap.size) {
	      process.env.NODE_ENV !== "production" ? warning(true, 'Tree is not connected. %s nodes were seen instead of %s', nodesSeen, blockMap.size) : void 0;
	      return false;
	    }

	    return true;
	  },

	  /**
	   * Checks that the block map is a connected tree with valid blocks
	   */
	  isValidTree: function isValidTree(blockMap) {
	    var _this = this;

	    var blocks = blockMap.toArray();

	    if (!blocks.every(function (block) {
	      return _this.isValidBlock(block, blockMap);
	    })) {
	      return false;
	    }

	    return this.isConnectedTree(blockMap);
	  }
	};
	DraftTreeInvariants_1 = DraftTreeInvariants;
	return DraftTreeInvariants_1;
}

export { requireDraftTreeInvariants as __require };
//# sourceMappingURL=DraftTreeInvariants.js.map
