/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.

#ifndef QXMLQUERY_P_H
#define QXMLQUERY_P_H

#include <QAbstractMessageHandler>
#include <QAbstractUriResolver>
#include <QPointer>
#include <QSourceLocation>
#include <QUrl>
#include <QVariant>
#include <QXmlName>
#include <QXmlNamePool>
#include <QXmlQuery>

#include <private/qacceltreebuilder_p.h>
#include <private/qacceltreeresourceloader_p.h>
#include <private/qcoloringmessagehandler_p.h>
#include <private/qcommonsequencetypes_p.h>
#include <private/qexpressionfactory_p.h>
#include <private/qfocus_p.h>
#include <private/qfunctionfactorycollection_p.h>
#include <private/qgenericdynamiccontext_p.h>
#include <private/qgenericstaticcontext_p.h>
#include <private/qnamepool_p.h>
#include <private/qnetworkaccessdelegator_p.h>
#include <private/qreferencecountedvalue_p.h>
#include <private/qresourcedelegator_p.h>
#include <private/qstaticfocuscontext_p.h>
#include <private/quriloader_p.h>
#include <private/qvariableloader_p.h>

QT_BEGIN_NAMESPACE

class QXmlQueryPrivate
{
public:

    inline QXmlQueryPrivate(const QXmlNamePool &np = QXmlNamePool()) : namePool(np)
                                                                     , messageHandler(0)
                                                                     , uriResolver(0)
                                                                     , queryLanguage(QXmlQuery::XQuery10)
                                                                     , m_networkAccessDelegator(new QPatternist::NetworkAccessDelegator(0, 0))
    {
        m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, variableLoader());
    }

    void detach()
    {
        if(m_variableLoader)
            m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d, m_variableLoader));

        delete m_networkAccessDelegator->m_variableURIManager;
        m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, m_variableLoader);

        if(m_resourceLoader)
        {
            const QPatternist::AccelTreeResourceLoader::Ptr nev(new QPatternist::AccelTreeResourceLoader(namePool.d,
                                                                                                         m_networkAccessDelegator));
            m_resourceLoader = QPatternist::DeviceResourceLoader::Ptr(new QPatternist::ResourceDelegator(m_resourceLoader->deviceURIs(),
                                                                                                   m_resourceLoader,
                                                                                                   nev));
        }
    }

    bool isValid()
    {
        return expression();
    }

    inline void recompileRequired()
    {
        m_expr.reset();
    }

    inline QPatternist::VariableLoader::Ptr variableLoader()
    {
        if(!m_variableLoader)
            m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d));

        return m_variableLoader;
    }

    inline QPatternist::StaticContext::Ptr staticContext()
    {
        if(m_staticContext && m_expr)
            return m_staticContext;
        /* Else, re-create the staticContext. */

        if(!messageHandler)
            messageHandler = new QPatternist::ColoringMessageHandler(ownerObject());

        if(!m_functionFactory)
        {
            if(queryLanguage == QXmlQuery::XSLT20)
                m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d);
            else
                m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
        }

        const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d,
                                                                                                                messageHandler,
                                                                                                                queryURI,
                                                                                                                m_functionFactory,
                                                                                                                queryLanguage));
        genericStaticContext->setResourceLoader(resourceLoader());

        genericStaticContext->setExternalVariableLoader(variableLoader());

        m_staticContext = genericStaticContext;

        if(!contextItem.isNull())
            m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext));
        else if(   queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField
                || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector
                || queryLanguage == QXmlQuery::XPath20)
            m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext));

        for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) {
            m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i));
        }

        return m_staticContext;
    }

    inline QPatternist::DynamicContext::Ptr dynamicContext(QAbstractXmlReceiver *const callback = 0)
    {
        const QPatternist::StaticContext::Ptr statContext(staticContext());
        Q_ASSERT(statContext);

        QPatternist::GenericDynamicContext::Ptr dynContext(new QPatternist::GenericDynamicContext(namePool.d, statContext->messageHandler(),
                                                                                                  statContext->sourceLocations()));

        QPatternist::AutoPtr<QPatternist::NodeBuilder> nodeBuilder(new QPatternist::AccelTreeBuilder<false>(QUrl(), QUrl(), namePool.d,
                                                                                                            dynContext.data()));
        dynContext->setNodeBuilder(nodeBuilder);

        dynContext->setResourceLoader(statContext->resourceLoader());
        dynContext->setExternalVariableLoader(statContext->externalVariableLoader());
        dynContext->setUriResolver(uriResolver);

        if(callback)
            dynContext->setOutputReceiver(callback);

        if(contextItem.isNull())
            return dynContext;
        else
        {
            QPatternist::DynamicContext::Ptr focus(new QPatternist::Focus(dynContext));
            QPatternist::Item::Iterator::Ptr it(QPatternist::makeSingletonIterator(QPatternist::Item::fromPublic(contextItem)));
            it->next();
            focus->setFocusIterator(it);
            return focus;
        }
    }

    inline QPatternist::AccelTreeResourceLoader::Ptr resourceLoader()
    {
        if(!m_resourceLoader)
            m_resourceLoader = (new QPatternist::AccelTreeResourceLoader(namePool.d, m_networkAccessDelegator));

        return m_resourceLoader;
    }

    void setRequiredType(const QPatternist::SequenceType::Ptr &seqType)
    {
        Q_ASSERT(seqType);
        if(!m_requiredType || m_requiredType->is(seqType))
            return;

        m_requiredType = seqType;
        m_staticContext.reset();
    }

    QPatternist::SequenceType::Ptr requiredType()
    {
        if(m_requiredType)
            return m_requiredType;
        else
        {
            m_requiredType = QPatternist::CommonSequenceTypes::ZeroOrMoreItems;
            return m_requiredType;
        }
    }

    QPatternist::Expression::Ptr expression(QIODevice *const queryDevice = 0)
    {
        if(m_expr && !queryDevice)
            return m_expr;

        /* If we need to update, but we don't have any source code, we can
         * never create an Expression. */
        if(!queryDevice)
            return QPatternist::Expression::Ptr();

        try
        {
            /* The static context has source locations, and they need to be
             * updated to the new query. */
            m_staticContext.reset();

            if(!m_expressionFactory)
                m_expressionFactory = QPatternist::ExpressionFactory::Ptr(new QPatternist::ExpressionFactory());

            m_expr = m_expressionFactory->createExpression(queryDevice, staticContext(),
                                                           queryLanguage,
                                                           requiredType(),
                                                           queryURI,
                                                           initialTemplateName);
        }
        catch(const QPatternist::Exception)
        {
            m_expr.reset();

            /* We don't call m_staticContext.reset() because it shouldn't be
             * necessary, since m_staticContext is changed when the expression
             * is changed. */
        }

        return m_expr;
    }

    inline void addAdditionalNamespaceBinding(const QXmlName &binding)
    {
        m_additionalNamespaceBindings.append(binding);
    }

    QXmlNamePool                                namePool;
    QPointer<QAbstractMessageHandler>           messageHandler;
    /**
     * Must be absolute and valid.
     */
    QUrl                                        queryURI;
    const QAbstractUriResolver *                uriResolver;
    QXmlItem                                    contextItem;
    QXmlName                                    initialTemplateName;

    inline void setExpressionFactory(const QPatternist::ExpressionFactory::Ptr &expr)
    {
        m_expressionFactory = expr;
    }

    QXmlQuery::QueryLanguage                    queryLanguage;
    QPointer<QNetworkAccessManager>             userNetworkManager;

    inline QObject *ownerObject()
    {
        if(!m_owner)
            m_owner = new QPatternist::ReferenceCountedValue<QObject>(new QObject());

        return m_owner->value;
    }

    QPatternist::ExpressionFactory::Ptr         m_expressionFactory;
    QPatternist::StaticContext::Ptr             m_staticContext;
    QPatternist::VariableLoader::Ptr            m_variableLoader;
    QPatternist::DeviceResourceLoader::Ptr      m_resourceLoader;
    /**
     * This is the AST for the query.
     */
    QPatternist::Expression::Ptr                m_expr;
    QPatternist::ReferenceCountedValue<QObject>::Ptr m_owner;

    /**
     * This is our effective network manager, that we end up using. The one the
     * user sets is userNetworkManager.
     */
    QPatternist::SequenceType::Ptr              m_requiredType;
    QPatternist::FunctionFactory::Ptr           m_functionFactory;
    QPatternist::NetworkAccessDelegator::Ptr    m_networkAccessDelegator;

    QList<QXmlName>                             m_additionalNamespaceBindings;
};

QT_END_NAMESPACE

#endif
