/****************************************************************************
**
** 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 Patternist_NamePool_H
#define Patternist_NamePool_H

#include <QHash>
#include <QReadLocker>
#include <QReadWriteLock>
#include <QSharedData>
#include <QString>
#include <QVector>
#include <QXmlName>

#include <QtXmlPatterns/private/qprimitives_p.h>

QT_BEGIN_NAMESPACE

namespace QPatternist
{
    /**
     * @short Store names such as namespace bindings and QNames and allows them to
     * be referenced in efficient ways.
     *
     * Once a string have been inserted it stays there and cannot be removed. The
     * only way to deallocate any string in the NamePool is to deallocate the
     * NamePool itself, as a whole.
     *
     * This class is not only reentrant, it is thread-safe in all sense of the
     * word. All functions of this class can be called concurrently. This is
     * achieved by internal locking.
     *
     * @author Frans Englich <frans.englich@nokia.com>
     * @todo Use QSubStrings, we can save very many heap allocations by that.
     * @todo Check limits
     */
    class Q_AUTOTEST_EXPORT NamePool : public QSharedData
    {
    public:
        typedef QExplicitlySharedDataPointer<NamePool> Ptr;

    private:
        friend class StandardNamespaces;

        enum
        {
            NoSuchValue         = -1,
            /**
             * This must be identical to the amount of members in
             * StandardNamespaces.
             */
            StandardNamespaceCount = 11,
            StandardPrefixCount = 9,
            StandardLocalNameCount = 141
        };

        QVector<QString> m_prefixes;
        QVector<QString> m_namespaces;
        QVector<QString> m_localNames;

        /**
         * This hash contains no essential data, but speeds up
         * finding a prefix in m_prefixes by mapping a prefix(the key) to
         * the index into m_prefixes(which the value is).
         *
         * In other words, one can skip this variable at the cost of having
         * to linearly loop over prefixes, in order to find the entry.
         */
        QHash<QString, QXmlName::PrefixCode> m_prefixMapping;

        /**
         * Same as m_prefixMapping but applies for URIs, and hence m_namespaces instead
         * of m_prefixes.
         */
        QHash<QString, QXmlName::NamespaceCode> m_namespaceMapping;

        QHash<QString, QXmlName::LocalNameCode> m_localNameMapping;

        enum DefaultCapacities
        {
            DefaultPrefixCapacity = 10,
            DefaultURICapacity = DefaultPrefixCapacity,
            /**
             * It looks like it's quite common with 40-60 different local names per XML
             * vocabulary. For background, see:
             *
             * - http://englich.wordpress.com/2007/01/11/representing-xml/
             * - http://englich.wordpress.com/2007/01/09/xmlstat/
             */
            DefaultLocalNameCapacity = 60
        };

    public:
        NamePool();

        /**
         * @short Allocates a namespace binding for @p prefix and @p uri.
         *
         * In the returned QXmlName, the local name is
         * StandardLocalNames::empty, and QXmlName::prefix() and
         * QXmlName::namespaceUri() returns @p prefix and @p uri, respectively.
         *
         * In older versions of this code, the class NamespaceBinding existed,
         * but as part of having the public class QXmlName, it was dropped and
         * a special interpretation/convention involving use of QXmlName was
         * adopted.
         */
        QXmlName allocateBinding(const QString &prefix, const QString &uri);

        QXmlName allocateQName(const QString &uri, const QString &localName, const QString &prefix = QString());

        inline QXmlName allocateQName(const QXmlName::NamespaceCode uri, const QString &ln)
        {
            /* We don't lock here, but we do in allocateLocalName(). */
            return QXmlName(uri, allocateLocalName(ln));
        }

        inline const QString &stringForLocalName(const QXmlName::LocalNameCode code) const
        {
            const QReadLocker l(&lock);
            return m_localNames.at(code);
        }

        inline const QString &stringForPrefix(const QXmlName::PrefixCode code) const
        {
            const QReadLocker l(&lock);
            return m_prefixes.at(code);
        }

        inline const QString &stringForNamespace(const QXmlName::NamespaceCode code) const
        {
            const QReadLocker l(&lock);
            return m_namespaces.at(code);
        }

        QString displayName(const QXmlName qName) const;

        inline QString toLexical(const QXmlName qName) const
        {
            const QReadLocker l(&lock);
            Q_ASSERT_X(!qName.isNull(), "", "It makes no sense to call toLexical() on a null name.");

            if(qName.hasPrefix())
            {
                const QString &p = m_prefixes.at(qName.prefix());
                return p + QLatin1Char(':') + m_localNames.at(qName.localName());
            }
            else
                return m_localNames.at(qName.localName());
        }

        inline QXmlName::NamespaceCode allocateNamespace(const QString &uri)
        {
            const QWriteLocker l(&lock);
            return unlockedAllocateNamespace(uri);
        }

        inline QXmlName::LocalNameCode allocateLocalName(const QString &ln)
        {
            const QWriteLocker l(&lock);
            return unlockedAllocateLocalName(ln);
        }

        inline QXmlName::PrefixCode allocatePrefix(const QString &prefix)
        {
            const QWriteLocker l(&lock);
            return unlockedAllocatePrefix(prefix);
        }

        QString toClarkName(const QXmlName &name) const;
        QXmlName fromClarkName(const QString &clarkName);

    private:
        /**
         * @note This function can not be called concurrently.
         */
        QXmlName::NamespaceCode unlockedAllocateNamespace(const QString &uri);

        /**
         * @note This function can not be called concurrently.
         */
        QXmlName::LocalNameCode unlockedAllocateLocalName(const QString &ln);

        /**
         * It's assumed that @p prefix is a valid @c NCName.
         *
         * @note This function can not be called concurrently.
         */
        QXmlName::PrefixCode unlockedAllocatePrefix(const QString &prefix);

        Q_DISABLE_COPY(NamePool)

        /**
         * @note This function can not be called concurrently.
         */
        const QString &displayPrefix(const QXmlName::NamespaceCode nc) const;

        mutable QReadWriteLock lock;
    };

    /**
     * @short Formats QName.
     *
     * @relates QXmlName
     */
    static inline QString formatKeyword(const NamePool::Ptr &np, const QXmlName name)
    {
        return QLatin1String("<span class='XQuery-keyword'>")   +
               escape(np->displayName(name))                    +
               QLatin1String("</span>");
    }

    /**
     * @see NamespaceResolver::Constants
     */
    class StandardNamespaces
    {
    public:
        enum ID
        {
            /**
             * This does not mean empty in the sense of "empty", but
             * in the sense of an empty string, "".
             *
             * Its value, zero, is significant.
             */
            empty = 0,
            fn,
            local,
            xml,
            xmlns,
            xs,
            xsi,
            xslt,
            /**
             * @short A special value that when passed as the namespace part
             * to NamespaceResolver::addBinding(), undeclares the prefix.
             *
             * This is used by the namespace prolog declaration.
             *
             * A dummy value is added to the name pool.
             */
            UndeclarePrefix,

            /**
             * Signals that a node shouldn't inherit namespaces from its parent. Must be used
             * with StandardPrefixes::StopNamespaceInheritance.
             */
            StopNamespaceInheritance,

            /**
             * A namespace used to identify for instance @c \#all template
             * mode in XSL-T.
             */
            InternalXSLT
        };
    };

    // const QString * a = &*qset.insert("foo");
    class StandardLocalNames
    {
    public:
        enum
        {
            abs,
            adjust_dateTime_to_timezone,
            adjust_date_to_timezone,
            adjust_time_to_timezone,
            all,
            arity,
            avg,
            base,
            base_uri,
            boolean,
            ceiling,
            codepoint_equal,
            codepoints_to_string,
            collection,
            compare,
            concat,
            contains,
            count,
            current,
            current_date,
            current_dateTime,
            current_time,
            data,
            dateTime,
            day_from_date,
            day_from_dateTime,
            days_from_duration,
            deep_equal,
            Default,
            default_collation,
            distinct_values,
            doc,
            doc_available,
            document,
            document_uri,
            element_available,
            empty,
            encode_for_uri,
            ends_with,
            error,
            escape_html_uri,
            exactly_one,
            exists,
            False,
            floor,
            function_available,
            function_name,
            generate_id,
            generic_string_join,
            hours_from_dateTime,
            hours_from_duration,
            hours_from_time,
            id,
            idref,
            implicit_timezone,
            index_of,
            in_scope_prefixes,
            insert_before,
            iri_to_uri,
            is_schema_aware,
            key,
            lang,
            last,
            local_name,
            local_name_from_QName,
            lower_case,
            matches,
            max,
            min,
            minutes_from_dateTime,
            minutes_from_duration,
            minutes_from_time,
            month_from_date,
            month_from_dateTime,
            months_from_duration,
            name,
            namespace_uri,
            namespace_uri_for_prefix,
            namespace_uri_from_QName,
            nilled,
            node_name,
            normalize_space,
            normalize_unicode,
            Not,
            number,
            one_or_more,
            position,
            prefix_from_QName,
            product_name,
            product_version,
            property_name,
            QName,
            remove,
            replace,
            resolve_QName,
            resolve_uri,
            reverse,
            root,
            round,
            round_half_to_even,
            seconds_from_dateTime,
            seconds_from_duration,
            seconds_from_time,
            sourceValue,
            starts_with,
            static_base_uri,
            string,
            string_join,
            string_length,
            string_to_codepoints,
            subsequence,
            substring,
            substring_after,
            substring_before,
            sum,
            supports_backwards_compatibility,
            supports_serialization,
            system_property,
            timezone_from_date,
            timezone_from_dateTime,
            timezone_from_time,
            tokenize,
            trace,
            translate,
            True,
            type_available,
            unordered,
            unparsed_entity_public_id,
            unparsed_entity_uri,
            unparsed_text,
            unparsed_text_available,
            upper_case,
            vendor,
            vendor_url,
            version,
            xml,
            xmlns,
            year_from_date,
            year_from_dateTime,
            years_from_duration,
            zero_or_one
        };
    };

    class StandardPrefixes
    {
    public:
        enum
        {
            /**
             * This does not mean empty in the sense of "empty", but
             * in the sense of an empty string, "".
             *
             * Its value, zero, is significant.
             */
            empty = 0,
            fn,
            local,
            xml,
            xmlns,
            xs,
            xsi,
            ns0,
            StopNamespaceInheritance
        };
    };
}

inline QXmlName::LocalNameCode QXmlName::localName() const
{
    return (m_qNameCode & LocalNameMask) >> LocalNameOffset;
}

inline QXmlName::PrefixCode QXmlName::prefix() const
{
    return (m_qNameCode & PrefixMask) >> PrefixOffset;
}

inline bool QXmlName::hasPrefix() const
{
    return prefix() != 0;
}

inline bool QXmlName::hasNamespace() const
{
    return namespaceURI() != 0;
}

inline QXmlName::NamespaceCode QXmlName::namespaceURI() const
{
    return (m_qNameCode & NamespaceMask) >> NamespaceOffset;
}

inline bool QXmlName::isLexicallyEqual(const QXmlName &other) const
{
    return (m_qNameCode & LexicalQNameMask) == (other.m_qNameCode & LexicalQNameMask);
}

inline void QXmlName::setPrefix(const PrefixCode c)
{
    m_qNameCode |= (c << PrefixOffset);
}

inline void QXmlName::setNamespaceURI(const NamespaceCode c)
{
    m_qNameCode |= (c << NamespaceOffset);
}

inline void QXmlName::setLocalName(const LocalNameCode c)
{
    m_qNameCode |= (c << LocalNameOffset);
}

inline QXmlName::Code QXmlName::code() const
{
    return m_qNameCode;
}

inline QXmlName::QXmlName(const NamespaceCode uri,
                          const LocalNameCode ln,
                          const PrefixCode p) : m_qNameCode((uri << NamespaceOffset) +
                                                            (ln << LocalNameOffset)  +
                                                            (p << PrefixOffset))
{
    /* We can't use members like prefix() here because if one of the
     * values are to large, they would overflow into the others. */
    Q_ASSERT_X(p <= MaximumPrefixes, "",
               qPrintable(QString::fromLatin1("NamePool prefix limits: max is %1, therefore %2 exceeds.").arg(MaximumPrefixes).arg(p)));
    Q_ASSERT_X(ln <= MaximumLocalNames, "",
               qPrintable(QString::fromLatin1("NamePool local name limits: max is %1, therefore %2 exceeds.").arg(MaximumLocalNames).arg(ln)));
    Q_ASSERT_X(uri <= MaximumNamespaces, "",
               qPrintable(QString::fromLatin1("NamePool namespace limits: max is %1, therefore %2 exceeds.").arg(MaximumNamespaces).arg(uri)));
}


Q_DECLARE_TYPEINFO(QPatternist::NamePool::Ptr, Q_MOVABLE_TYPE);

QT_END_NAMESPACE

#endif
