/*
 * Copyright (C) 2000 Peter Kelly (pmk@post.com)
 * Copyright (C) 2005-2017 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2008 Holger Hans Peter Freyther
 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 *
 * 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.
 */

#include "config.h"
#include "XMLDocumentParser.h"

#include "CDATASection.h"
#include "Comment.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentType.h"
#include "ElementAncestorIterator.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameView.h"
#include "HTMLLinkElement.h"
#include "HTMLNames.h"
#include "HTMLStyleElement.h"
#include "ImageLoader.h"
#include "PendingScript.h"
#include "ProcessingInstruction.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include "SVGForeignObjectElement.h"
#include "SVGNames.h"
#include "SVGStyleElement.h"
#include "ScriptElement.h"
#include "ScriptSourceCode.h"
#include "StyleScope.h"
#include "TextResourceDecoder.h"
#include "TreeDepthLimit.h"
#include "XMLNSNames.h"
#include <wtf/Ref.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>

namespace WebCore {

using namespace HTMLNames;

void XMLDocumentParser::pushCurrentNode(ContainerNode* n)
{
    ASSERT(n);
    ASSERT(m_currentNode);
    if (n != document())
        n->ref();
    m_currentNodeStack.append(m_currentNode);
    m_currentNode = n;
    if (m_currentNodeStack.size() > maxDOMTreeDepth)
        handleError(XMLErrors::fatal, "Excessive node nesting.", textPosition());
}

void XMLDocumentParser::popCurrentNode()
{
    if (!m_currentNode)
        return;
    ASSERT(m_currentNodeStack.size());

    if (m_currentNode != document())
        m_currentNode->deref();

    m_currentNode = m_currentNodeStack.last();
    m_currentNodeStack.removeLast();
}

void XMLDocumentParser::clearCurrentNodeStack()
{
    if (m_currentNode && m_currentNode != document())
        m_currentNode->deref();
    m_currentNode = nullptr;
    m_leafTextNode = nullptr;

    if (m_currentNodeStack.size()) { // Aborted parsing.
        for (size_t i = m_currentNodeStack.size() - 1; i != 0; --i)
            m_currentNodeStack[i]->deref();
        if (m_currentNodeStack[0] && m_currentNodeStack[0] != document())
            m_currentNodeStack[0]->deref();
        m_currentNodeStack.clear();
    }
}

void XMLDocumentParser::insert(SegmentedString&&)
{
    ASSERT_NOT_REACHED();
}

void XMLDocumentParser::append(RefPtr<StringImpl>&& inputSource)
{
    String source { WTFMove(inputSource) };

    if (m_sawXSLTransform || !m_sawFirstElement)
        m_originalSourceForTransform.append(source);

    if (isStopped() || m_sawXSLTransform)
        return;

    if (m_parserPaused) {
        m_pendingSrc.append(source);
        return;
    }

    doWrite(source);

    // After parsing, dispatch image beforeload events.
    ImageLoader::dispatchPendingBeforeLoadEvents(nullptr);
}

void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* m, TextPosition position)
{
    if (!m_xmlErrors)
        m_xmlErrors = makeUnique<XMLErrors>(*document());
    m_xmlErrors->handleError(type, m, position);
    if (type != XMLErrors::warning)
        m_sawError = true;
    if (type == XMLErrors::fatal)
        stopParsing();
}

void XMLDocumentParser::createLeafTextNode()
{
    if (m_leafTextNode)
        return;

    ASSERT(m_bufferedText.size() == 0);
    ASSERT(!m_leafTextNode);
    m_leafTextNode = Text::create(m_currentNode->document(), "");
    m_currentNode->parserAppendChild(*m_leafTextNode);
}

bool XMLDocumentParser::updateLeafTextNode()
{
    if (isStopped())
        return false;

    if (!m_leafTextNode)
        return true;

    // This operation might fire mutation event, see below.
    m_leafTextNode->appendData(String::fromUTF8(reinterpret_cast<const char*>(m_bufferedText.data()), m_bufferedText.size()));
    m_bufferedText = { };

    m_leafTextNode = nullptr;

    // Hence, we need to check again whether the parser is stopped, since mutation
    // event handlers executed by appendData might have detached this parser.
    return !isStopped();
}

void XMLDocumentParser::detach()
{
    clearCurrentNodeStack();
    ScriptableDocumentParser::detach();
}

void XMLDocumentParser::end()
{
    // XMLDocumentParserLibxml2 will do bad things to the document if doEnd() is called.
    // I don't believe XMLDocumentParserQt needs doEnd called in the fragment case.
    ASSERT(!m_parsingFragment);

    doEnd();

    // doEnd() call above can detach the parser and null out its document.
    // In that case, we just bail out.
    if (isDetached())
        return;

    // doEnd() could process a script tag, thus pausing parsing.
    if (m_parserPaused)
        return;

    if (m_sawError && !isStopped()) {
        insertErrorMessageBlock();
        if (isDetached()) // Inserting an error message may have ran arbitrary scripts.
            return;
    } else {
        updateLeafTextNode();
        document()->styleScope().didChangeStyleSheetEnvironment();
    }

    if (isParsing())
        prepareToStopParsing();
    document()->setReadyState(Document::Interactive);
    clearCurrentNodeStack();
    document()->finishedParsing();
}

void XMLDocumentParser::finish()
{
    // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
    // makes sense to call any methods on DocumentParser once it's been stopped.
    // However, FrameLoader::stop calls DocumentParser::finish unconditionally.

    Ref<XMLDocumentParser> protectedThis(*this);

    if (m_parserPaused)
        m_finishCalled = true;
    else
        end();
}

void XMLDocumentParser::insertErrorMessageBlock()
{
    ASSERT(m_xmlErrors);
    m_xmlErrors->insertErrorMessageBlock();
}

void XMLDocumentParser::notifyFinished(PendingScript& pendingScript)
{
    ASSERT(&pendingScript == m_pendingScript.get());

    // JavaScript can detach this parser, make sure it's kept alive even if detached.
    Ref<XMLDocumentParser> protectedThis(*this);

    m_pendingScript = nullptr;
    pendingScript.clearClient();

    pendingScript.element().executePendingScript(pendingScript);

    if (!isDetached() && !m_requestingScript)
        resumeParsing();
}

bool XMLDocumentParser::isWaitingForScripts() const
{
    return m_pendingScript;
}

void XMLDocumentParser::pauseParsing()
{
    ASSERT(!m_parserPaused);

    if (m_parsingFragment)
        return;

    m_parserPaused = true;
}

struct XMLParsingNamespaces {
    AtomString defaultNamespace;
    HashMap<AtomString, AtomString> prefixNamespaces;
};

static XMLParsingNamespaces findXMLParsingNamespaces(Element* contextElement)
{
    if (!contextElement)
        return { };

    XMLParsingNamespaces result;

    bool stopLookingForDefaultNamespace = false;

    for (auto& element : lineageOfType<Element>(*contextElement)) {
        if (is<SVGForeignObjectElement>(element))
            stopLookingForDefaultNamespace = true;
        else if (!stopLookingForDefaultNamespace)
            result.defaultNamespace = element.namespaceURI();

        if (!element.hasAttributes())
            continue;

        for (auto& attribute : element.attributesIterator()) {
            if (attribute.prefix() == xmlnsAtom())
                result.prefixNamespaces.set(attribute.localName(), attribute.value());
        }
    }

    return result;
}

bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
{
    if (!chunk.length())
        return true;

    // FIXME: We need to implement the HTML5 XML Fragment parsing algorithm:
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm
    // For now we have a hack for script/style innerHTML support:
    if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag->localName()) || contextElement->hasLocalName(HTMLNames::styleTag->localName()))) {
        fragment.parserAppendChild(fragment.document().createTextNode(chunk));
        return true;
    }

    auto namespaces = findXMLParsingNamespaces(contextElement);
    auto parser = XMLDocumentParser::create(fragment, WTFMove(namespaces.prefixNamespaces), namespaces.defaultNamespace, parserContentPolicy);
    bool wellFormed = parser->appendFragmentSource(chunk);
    // Do not call finish(). The finish() and doEnd() implementations touch the main document and loader and can cause crashes in the fragment case.
    parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
    return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than Document::wellFormed().
}

} // namespace WebCore
