/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004-2018 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include "CollectionType.h"
#include "Node.h"

namespace WebCore {

class HTMLCollection;
class RadioNodeList;
class RenderElement;

const int initialNodeVectorSize = 11; // Covers 99.5%. See webkit.org/b/80706
typedef Vector<Ref<Node>, initialNodeVectorSize> NodeVector;

class ContainerNode : public Node {
    WTF_MAKE_ISO_ALLOCATED(ContainerNode);
public:
    virtual ~ContainerNode();

    Node* firstChild() const { return m_firstChild; }
    static ptrdiff_t firstChildMemoryOffset() { return OBJECT_OFFSETOF(ContainerNode, m_firstChild); }
    Node* lastChild() const { return m_lastChild; }
    static ptrdiff_t lastChildMemoryOffset() { return OBJECT_OFFSETOF(ContainerNode, m_lastChild); }
    bool hasChildNodes() const { return m_firstChild; }
    bool hasOneChild() const { return m_firstChild && m_firstChild == m_lastChild; }

    bool directChildNeedsStyleRecalc() const { return hasStyleFlag(NodeStyleFlag::DirectChildNeedsStyleResolution); }
    void setDirectChildNeedsStyleRecalc() { setStyleFlag(NodeStyleFlag::DirectChildNeedsStyleResolution); }

    WEBCORE_EXPORT unsigned countChildNodes() const;
    WEBCORE_EXPORT Node* traverseToChildAt(unsigned) const;

    ExceptionOr<void> insertBefore(Node& newChild, Node* refChild);
    ExceptionOr<void> replaceChild(Node& newChild, Node& oldChild);
    WEBCORE_EXPORT ExceptionOr<void> removeChild(Node& child);
    WEBCORE_EXPORT ExceptionOr<void> appendChild(Node& newChild);
    void stringReplaceAll(const String&);
    void replaceAll(Node*);

    // These methods are only used during parsing.
    // They don't send DOM mutation events or handle reparenting.
    // However, arbitrary code may be run by beforeload handlers.
    void parserAppendChild(Node&);
    void parserRemoveChild(Node&);
    void parserInsertBefore(Node& newChild, Node& refChild);

    void removeChildren();

    void takeAllChildrenFrom(ContainerNode*);

    void cloneChildNodes(ContainerNode& clone);

    struct ChildChange {
        enum class Type : uint8_t { ElementInserted, ElementRemoved, TextInserted, TextRemoved, TextChanged, AllChildrenRemoved, NonContentsChildRemoved, NonContentsChildInserted, AllChildrenReplaced };
        enum class Source : bool { Parser, API };

        ChildChange::Type type;
        Element* previousSiblingElement;
        Element* nextSiblingElement;
        ChildChange::Source source;

        bool isInsertion() const
        {
            switch (type) {
            case ChildChange::Type::ElementInserted:
            case ChildChange::Type::TextInserted:
            case ChildChange::Type::NonContentsChildInserted:
            case ChildChange::Type::AllChildrenReplaced:
                return true;
            case ChildChange::Type::ElementRemoved:
            case ChildChange::Type::TextRemoved:
            case ChildChange::Type::TextChanged:
            case ChildChange::Type::AllChildrenRemoved:
            case ChildChange::Type::NonContentsChildRemoved:
                return false;
            }
            ASSERT_NOT_REACHED();
            return false;
        }
    };
    virtual void childrenChanged(const ChildChange&);

    ExceptionOr<void> appendChild(ChildChange::Source, Node& newChild);

    void disconnectDescendantFrames();

    RenderElement* renderer() const;

    // Return a bounding box in absolute coordinates enclosing this node and all its descendants.
    // This gives the area within which events may get handled by a hander registered on this node.
    virtual LayoutRect absoluteEventHandlerBounds(bool& /* includesFixedPositionElements */) { return LayoutRect(); }

    WEBCORE_EXPORT ExceptionOr<Element*> querySelector(const String& selectors);
    WEBCORE_EXPORT ExceptionOr<Ref<NodeList>> querySelectorAll(const String& selectors);

    WEBCORE_EXPORT Ref<HTMLCollection> getElementsByTagName(const AtomString&);
    WEBCORE_EXPORT Ref<HTMLCollection> getElementsByTagNameNS(const AtomString& namespaceURI, const AtomString& localName);
    WEBCORE_EXPORT Ref<NodeList> getElementsByName(const String& elementName);
    WEBCORE_EXPORT Ref<HTMLCollection> getElementsByClassName(const AtomString& classNames);
    Ref<RadioNodeList> radioNodeList(const AtomString&);

    // From the ParentNode interface - https://dom.spec.whatwg.org/#interface-parentnode
    WEBCORE_EXPORT Ref<HTMLCollection> children();
    WEBCORE_EXPORT Element* firstElementChild() const;
    WEBCORE_EXPORT Element* lastElementChild() const;
    WEBCORE_EXPORT unsigned childElementCount() const;
    ExceptionOr<void> append(Vector<NodeOrString>&&);
    ExceptionOr<void> prepend(Vector<NodeOrString>&&);

    ExceptionOr<void> replaceChildren(Vector<NodeOrString>&&);

    ExceptionOr<void> ensurePreInsertionValidity(Node& newChild, Node* refChild);

protected:
    explicit ContainerNode(Document&, ConstructionType = CreateContainer);

    friend void addChildNodesToDeletionQueue(Node*& head, Node*& tail, ContainerNode&);

    void removeDetachedChildren();
    void setFirstChild(Node* child) { m_firstChild = child; }
    void setLastChild(Node* child) { m_lastChild = child; }

    HTMLCollection* cachedHTMLCollection(CollectionType);

private:
    void executePreparedChildrenRemoval();
    enum class DeferChildrenChanged { Yes, No };
    NodeVector removeAllChildrenWithScriptAssertion(ChildChange::Source, DeferChildrenChanged = DeferChildrenChanged::No);
    bool removeNodeWithScriptAssertion(Node&, ChildChange::Source);
    ExceptionOr<void> removeSelfOrChildNodesForInsertion(Node&, NodeVector&);

    void removeBetween(Node* previousChild, Node* nextChild, Node& oldChild);
    ExceptionOr<void> appendChildWithoutPreInsertionValidityCheck(Node&);
    void insertBeforeCommon(Node& nextChild, Node& oldChild);
    void appendChildCommon(Node&);

    void rebuildSVGExtensionsElementsIfNecessary();

    bool isContainerNode() const = delete;

    Node* m_firstChild { nullptr };
    Node* m_lastChild { nullptr };
};

inline ContainerNode::ContainerNode(Document& document, ConstructionType type)
    : Node(document, type)
{
}

inline unsigned Node::countChildNodes() const
{
    if (!is<ContainerNode>(*this))
        return 0;
    return downcast<ContainerNode>(*this).countChildNodes();
}

inline Node* Node::traverseToChildAt(unsigned index) const
{
    if (!is<ContainerNode>(*this))
        return nullptr;
    return downcast<ContainerNode>(*this).traverseToChildAt(index);
}

inline Node* Node::firstChild() const
{
    if (!is<ContainerNode>(*this))
        return nullptr;
    return downcast<ContainerNode>(*this).firstChild();
}

inline Node* Node::lastChild() const
{
    if (!is<ContainerNode>(*this))
        return nullptr;
    return downcast<ContainerNode>(*this).lastChild();
}

inline Node& Node::rootNode() const
{
    if (isInTreeScope())
        return treeScope().rootNode();
    return traverseToRootNode();
}

inline NodeVector collectChildNodes(Node& node)
{
    NodeVector children;
    for (Node* child = node.firstChild(); child; child = child->nextSibling())
        children.append(*child);
    return children;
}

class ChildNodesLazySnapshot {
    WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot);
    WTF_MAKE_FAST_ALLOCATED;
public:
    explicit ChildNodesLazySnapshot(Node& parentNode)
        : m_currentNode(parentNode.firstChild())
        , m_currentIndex(0)
        , m_hasSnapshot(false)
    {
        m_nextSnapshot = latestSnapshot;
        latestSnapshot = this;
    }

    ALWAYS_INLINE ~ChildNodesLazySnapshot()
    {
        latestSnapshot = m_nextSnapshot;
    }

    // Returns 0 if there is no next Node.
    RefPtr<Node> nextNode()
    {
        if (LIKELY(!hasSnapshot())) {
            RefPtr<Node> node = WTFMove(m_currentNode);
            if (node)
                m_currentNode = node->nextSibling();
            return node;
        }
        if (m_currentIndex >= m_snapshot.size())
            return nullptr;
        return m_snapshot[m_currentIndex++];
    }

    void takeSnapshot()
    {
        if (hasSnapshot())
            return;
        m_hasSnapshot = true;
        Node* node = m_currentNode.get();
        while (node) {
            m_snapshot.append(node);
            node = node->nextSibling();
        }
    }

    ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; }
    bool hasSnapshot() { return m_hasSnapshot; }

    static void takeChildNodesLazySnapshot()
    {
        ChildNodesLazySnapshot* snapshot = latestSnapshot;
        while (snapshot && !snapshot->hasSnapshot()) {
            snapshot->takeSnapshot();
            snapshot = snapshot->nextSnapshot();
        }
    }

private:
    static ChildNodesLazySnapshot* latestSnapshot;

    RefPtr<Node> m_currentNode;
    unsigned m_currentIndex;
    bool m_hasSnapshot;
    Vector<RefPtr<Node>> m_snapshot; // Lazily instantiated.
    ChildNodesLazySnapshot* m_nextSnapshot;
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ContainerNode)
    static bool isType(const WebCore::Node& node) { return node.isContainerNode(); }
SPECIALIZE_TYPE_TRAITS_END()
