/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtDebug>

#include <private/qacceltreeresourceloader_p.h>
#include <private/qnetworkaccessdelegator_p.h>

#include "Global.h"
#include "TestBaseLine.h"
#include "TestGroup.h"

#include "XSLTTestSuiteHandler.h"

using namespace QPatternistSDK;

static QNetworkAccessManager *s_networkAccessManager = 0;

static void cleanupNetworkAccessManager()
{
    delete s_networkAccessManager;
    s_networkAccessManager = 0;

}
static QNetworkAccessManager *networkAccessManager()
{
    if (!s_networkAccessManager) {
        s_networkAccessManager = new QNetworkAccessManager;
        qAddPostRoutine(cleanupNetworkAccessManager);
    }
    return s_networkAccessManager;
}

XSLTTestSuiteHandler::XSLTTestSuiteHandler(const QUrl &catalogFile) : m_ts(0)
                                                                    , m_tc(0)
                                                                    , m_baseLine(0)
                                                                    , m_catalogFile(catalogFile)
                                                                    , m_removeTestcase(false)
{
    const QPatternist::NetworkAccessDelegator::Ptr networkDelegator(new QPatternist::NetworkAccessDelegator(networkAccessManager(), networkAccessManager()));

    m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::AccelTreeResourceLoader(Global::namePool(),
                                                                                                 networkDelegator));
    Q_ASSERT(!m_catalogFile.isRelative());
}

bool XSLTTestSuiteHandler::startElement(const QStringRef &namespaceURI, const QStringRef &localName,
                                        const QStringRef & /*qName*/, const QXmlStreamAttributes &atts)
{
    if(namespaceURI != Global::xsltsCatalogNS)
        return true;

    /* The elements are handled roughly in the order of highest occurrence in the catalog file. */
    if(localName == QLatin1String("testcase"))
    {
        /* We pass m_ts temporarily, and change it later. */
        m_tc = new XQTSTestCase(TestCase::Standard, 0, QXmlQuery::XSLT20);

        m_currentQueryPath =
                m_queryOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")).toString()));
        m_currentBaselinePath =
                m_baselineOffset.resolved(QUrl(atts.value(QLatin1String("FilePath")).toString()));
    }
    else if(localName == QLatin1String("stylesheet"))
        m_tc->setQueryPath(
                m_currentQueryPath.resolved(atts.value(QLatin1String("file")).toString()));
    else if(localName == QLatin1String("error"))
    {
        m_baseLine = new TestBaseLine(TestBaseLine::ExpectedError);
        m_baseLine->setDetails(atts.value(QLatin1String("error-id")).toString());
        m_tc->addBaseLine(m_baseLine);
    }
    else if(localName == QLatin1String("testcases"))
    {
        m_ts = new TestSuite();
        m_ts->setVersion(atts.value(QLatin1String("testSuiteVersion")).toString());

        m_queryOffset =
                m_catalogFile.resolved(atts.value(QLatin1String("InputOffsetPath")).toString());
        m_baselineOffset =
                m_catalogFile.resolved(atts.value(QLatin1String("ResultOffsetPath")).toString());
        m_sourceOffset =
                m_catalogFile.resolved(atts.value(QLatin1String("InputOffsetPath")).toString());
    }
    else if(localName == QLatin1String("source-document"))
    {
        if(atts.value(QLatin1String("role")) == QLatin1String("principal"))
            m_tc->setContextItemSource(
                    m_sourceOffset.resolved(QUrl(atts.value(QLatin1String("file")).toString())));
    }
    else if(localName == QLatin1String("result-document"))
    {
        m_baseLine = new TestBaseLine(
                TestBaseLine::identifierFromString(atts.value(QLatin1String("type")).toString()));
        m_baseLine->setDetails(
                m_currentBaselinePath.resolved(atts.value(QLatin1String("file")).toString())
                        .toString());
        m_tc->addBaseLine(m_baseLine);
    }
    else if(localName == QLatin1String("discretionary-feature"))
    {
        const QString feature(atts.value(QLatin1String("name")).toString());

        m_removeTestcase = feature == QLatin1String("schema_aware") ||
                           feature == QLatin1String("namespace_axis") ||
                           feature == QLatin1String("disabling_output_escaping") ||
                           feature == QLatin1String("XML_1.1");
    }
    else if(localName == QLatin1String("discretionary-choice"))
    {
        m_baseLine = new TestBaseLine(TestBaseLine::ExpectedError);
        m_baseLine->setDetails(atts.value(QLatin1String("name")).toString());
        m_tc->addBaseLine(m_baseLine);
        const QString feature(atts.value(QLatin1String("name")).toString());

        m_removeTestcase = feature == QLatin1String("schema_aware") ||
                           feature == QLatin1String("namespace_axis") ||
                           feature == QLatin1String("disabling_output_escaping") ||
                           feature == QLatin1String("XML_1.1");
    }
    else if(localName == QLatin1String("entry-named-template"))
    {
        const QString name(atts.value(QLatin1String("qname")).toString());

        if(!name.contains(QLatin1Char(':')))
        {
            // TODO do namespace processing
            const QXmlName complete(Global::namePool()->allocateQName(QString(), name));

            m_tc->setInitialTemplateName(complete);
        }
    }

    return true;
}

TestGroup *XSLTTestSuiteHandler::containerFor(const QString &name)
{
    TestGroup *& c = m_containers[name];

    if(!c)
    {
        c = new TestGroup(m_ts);
        c->setTitle(name);
        Q_ASSERT(c);
        m_ts->appendChild(c);
    }

    return c;
}

bool XSLTTestSuiteHandler::endElement(const QStringRef &namespaceURI,
                                      const QStringRef &localName,
                                      const QStringRef &/*qName*/)
{
    if(namespaceURI != Global::xsltsCatalogNS)
        return true;

    /* The elements are handled roughly in the order of highest occurrence in the catalog file. */
    if(localName == QLatin1String("description"))
    {
        if(m_tc)
        {
            /* We're inside a <testcase>, so the <description> belongs
             * to the testcase. */
            m_tc->setDescription(m_ch.simplified());
        }
    }
    else if(localName == QLatin1String("testcase"))
    {
        Q_ASSERT(m_tc->baseLines().count() >= 1);
        Q_ASSERT(m_resourceLoader);
        // TODO can this be removed?
        m_tc->setExternalVariableLoader(QPatternist::ExternalVariableLoader::Ptr
                                                (new ExternalSourceLoader(m_tcSourceInputs,
                                                                          m_resourceLoader)));
        m_tcSourceInputs.clear();

        if(!m_removeTestcase)
        {
            /*
            TestContainer *const container = containerFor(m_currentCategory);
            delete m_tc;
            container->removeLast();
            */
            TestContainer *const container = containerFor(m_currentCategory);
            m_tc->setParent(container);
            Q_ASSERT(m_tc);
            container->appendChild(m_tc);
        }

        m_tc = 0;
        m_removeTestcase = false;
    }
    else if(localName == QLatin1String("name"))
        m_tc->setName(m_ch);
    else if(localName == QLatin1String("creator"))
        m_tc->setCreator(m_ch);
    else if(localName == QLatin1String("contextItem"))
        m_contextItemSource = m_ch;
    else if(localName == QLatin1String("category"))
        m_currentCategory = m_ch;

    return true;
}

bool XSLTTestSuiteHandler::characters(const QStringRef &ch)
{
    m_ch = ch.toString();
    return true;
}

TestSuite *XSLTTestSuiteHandler::testSuite() const
{
    return m_ts;
}

// vim: et:ts=4:sw=4:sts=4

