/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtDBus 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$
**
****************************************************************************/

#include "qdbusargument_p.h"
#include "qdbusconnection.h"

#include <qscopedpointer.h>

#include <stdlib.h>

QT_BEGIN_NAMESPACE

template <typename T>
static inline T qIterGet(DBusMessageIter *it)
{
    // Use a union of expected and largest type q_dbus_message_iter_get_basic
    // will return to ensure reading the wrong basic type does not result in
    // stack overwrite
    union {
        // The value to be extracted
        T t;
        // Largest type that q_dbus_message_iter_get_basic will return
        // according to dbus_message_iter_get_basic API documentation
        dbus_uint64_t maxValue;
        // A pointer to ensure no stack overwrite in case there is a platform
        // where sizeof(void*) > sizeof(dbus_uint64_t)
        void* ptr;
    } value;

    // Initialize the value in case a narrower type is extracted to it.
    // Note that the result of extracting a narrower type in place of a wider
    // one and vice-versa will be platform-dependent.
    value.t = T();

    q_dbus_message_iter_get_basic(it, &value);
    q_dbus_message_iter_next(it);
    return value.t;
}

QDBusDemarshaller::~QDBusDemarshaller()
{
}

inline QString QDBusDemarshaller::currentSignature()
{
    char *sig = q_dbus_message_iter_get_signature(&iterator);
    QString retval = QString::fromUtf8(sig);
    q_dbus_free(sig);

    return retval;
}

inline uchar QDBusDemarshaller::toByte()
{
    return qIterGet<uchar>(&iterator);
}

inline bool QDBusDemarshaller::toBool()
{
    return bool(qIterGet<dbus_bool_t>(&iterator));
}

inline ushort QDBusDemarshaller::toUShort()
{
    return qIterGet<dbus_uint16_t>(&iterator);
}

inline short QDBusDemarshaller::toShort()
{
    return qIterGet<dbus_int16_t>(&iterator);
}

inline int QDBusDemarshaller::toInt()
{
    return qIterGet<dbus_int32_t>(&iterator);
}

inline uint QDBusDemarshaller::toUInt()
{
    return qIterGet<dbus_uint32_t>(&iterator);
}

inline qlonglong QDBusDemarshaller::toLongLong()
{
    return qIterGet<qlonglong>(&iterator);
}

inline qulonglong QDBusDemarshaller::toULongLong()
{
    return qIterGet<qulonglong>(&iterator);
}

inline double QDBusDemarshaller::toDouble()
{
    return qIterGet<double>(&iterator);
}

inline QString QDBusDemarshaller::toStringUnchecked()
{
    return QString::fromUtf8(qIterGet<char *>(&iterator));
}

inline QString QDBusDemarshaller::toString()
{
    if (isCurrentTypeStringLike())
        return toStringUnchecked();
    else
        return QString();
}

inline QDBusObjectPath QDBusDemarshaller::toObjectPathUnchecked()
 {
     return QDBusObjectPath(QString::fromUtf8(qIterGet<char *>(&iterator)));
 }

inline QDBusObjectPath QDBusDemarshaller::toObjectPath()
{
    if (isCurrentTypeStringLike())
        return toObjectPathUnchecked();
    else
        return QDBusObjectPath();
}

inline QDBusSignature QDBusDemarshaller::toSignatureUnchecked()
 {
     return QDBusSignature(QString::fromUtf8(qIterGet<char *>(&iterator)));
 }

inline QDBusSignature QDBusDemarshaller::toSignature()
{
    if (isCurrentTypeStringLike())
        return toSignatureUnchecked();
    else
        return QDBusSignature();
}

inline QDBusUnixFileDescriptor QDBusDemarshaller::toUnixFileDescriptor()
{
    QDBusUnixFileDescriptor fd;
    fd.giveFileDescriptor(qIterGet<dbus_int32_t>(&iterator));
    return fd;
}

inline QDBusVariant QDBusDemarshaller::toVariant()
{
    QDBusDemarshaller sub(capabilities);
    sub.message = q_dbus_message_ref(message);
    q_dbus_message_iter_recurse(&iterator, &sub.iterator);
    q_dbus_message_iter_next(&iterator);

    return QDBusVariant( sub.toVariantInternal() );
}

QDBusArgument::ElementType QDBusDemarshaller::currentType()
{
    switch (q_dbus_message_iter_get_arg_type(&iterator)) {
    case DBUS_TYPE_BYTE:
    case DBUS_TYPE_INT16:
    case DBUS_TYPE_UINT16:
    case DBUS_TYPE_INT32:
    case DBUS_TYPE_UINT32:
    case DBUS_TYPE_INT64:
    case DBUS_TYPE_UINT64:
    case DBUS_TYPE_BOOLEAN:
    case DBUS_TYPE_DOUBLE:
    case DBUS_TYPE_STRING:
    case DBUS_TYPE_OBJECT_PATH:
    case DBUS_TYPE_SIGNATURE:
        return QDBusArgument::BasicType;

    case DBUS_TYPE_VARIANT:
        return QDBusArgument::VariantType;

    case DBUS_TYPE_ARRAY:
        switch (q_dbus_message_iter_get_element_type(&iterator)) {
        case DBUS_TYPE_BYTE:
        case DBUS_TYPE_STRING:
            // QByteArray and QStringList
            return QDBusArgument::BasicType;
        case DBUS_TYPE_DICT_ENTRY:
            return QDBusArgument::MapType;
        default:
            return QDBusArgument::ArrayType;
        }

    case DBUS_TYPE_STRUCT:
        return QDBusArgument::StructureType;
    case DBUS_TYPE_DICT_ENTRY:
        return QDBusArgument::MapEntryType;

    case DBUS_TYPE_UNIX_FD:
        return capabilities & QDBusConnection::UnixFileDescriptorPassing ?
                    QDBusArgument::BasicType : QDBusArgument::UnknownType;

    case DBUS_TYPE_INVALID:
        return QDBusArgument::UnknownType;

//    default:
//        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
//                 q_dbus_message_iter_get_arg_type(&iterator),
//                 q_dbus_message_iter_get_arg_type(&iterator));
    }
    return QDBusArgument::UnknownType;
}

QVariant QDBusDemarshaller::toVariantInternal()
{
    switch (q_dbus_message_iter_get_arg_type(&iterator)) {
    case DBUS_TYPE_BYTE:
        return QVariant::fromValue(toByte());
    case DBUS_TYPE_INT16:
        return QVariant::fromValue(toShort());
    case DBUS_TYPE_UINT16:
        return QVariant::fromValue(toUShort());
    case DBUS_TYPE_INT32:
        return toInt();
    case DBUS_TYPE_UINT32:
        return toUInt();
    case DBUS_TYPE_DOUBLE:
        return toDouble();
    case DBUS_TYPE_BOOLEAN:
        return toBool();
    case DBUS_TYPE_INT64:
        return toLongLong();
    case DBUS_TYPE_UINT64:
        return toULongLong();
    case DBUS_TYPE_STRING:
        return toStringUnchecked();
    case DBUS_TYPE_OBJECT_PATH:
        return QVariant::fromValue(toObjectPathUnchecked());
    case DBUS_TYPE_SIGNATURE:
        return QVariant::fromValue(toSignatureUnchecked());
    case DBUS_TYPE_VARIANT:
        return QVariant::fromValue(toVariant());

    case DBUS_TYPE_ARRAY:
        switch (q_dbus_message_iter_get_element_type(&iterator)) {
        case DBUS_TYPE_BYTE:
            // QByteArray
            return toByteArrayUnchecked();
        case DBUS_TYPE_STRING:
            return toStringListUnchecked();
        case DBUS_TYPE_DICT_ENTRY:
            return QVariant::fromValue(duplicate());

        default:
            return QVariant::fromValue(duplicate());
        }

    case DBUS_TYPE_STRUCT:
        return QVariant::fromValue(duplicate());

    case DBUS_TYPE_UNIX_FD:
        if (capabilities & QDBusConnection::UnixFileDescriptorPassing)
            return QVariant::fromValue(toUnixFileDescriptor());
        Q_FALLTHROUGH();

    default:
//        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
//                 q_dbus_message_iter_get_arg_type(&iterator),
//                 q_dbus_message_iter_get_arg_type(&iterator));
        char *ptr = nullptr;
        ptr += q_dbus_message_iter_get_arg_type(&iterator);
        q_dbus_message_iter_next(&iterator);

        // I hope you never dereference this pointer!
        return QVariant::fromValue<void *>(ptr);
    };
}

bool QDBusDemarshaller::isCurrentTypeStringLike()
{
    const int type = q_dbus_message_iter_get_arg_type(&iterator);
    switch (type) {
    case DBUS_TYPE_STRING:  //FALLTHROUGH
    case DBUS_TYPE_OBJECT_PATH:  //FALLTHROUGH
    case DBUS_TYPE_SIGNATURE:
        return true;
    default:
        return false;
    }
}

QStringList QDBusDemarshaller::toStringListUnchecked()
{
    QStringList list;

    QDBusDemarshaller sub(capabilities);
    q_dbus_message_iter_recurse(&iterator, &sub.iterator);
    q_dbus_message_iter_next(&iterator);
    while (!sub.atEnd())
        list.append(sub.toStringUnchecked());

    return list;
}

QStringList QDBusDemarshaller::toStringList()
{
    if (q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_ARRAY
            && q_dbus_message_iter_get_element_type(&iterator) == DBUS_TYPE_STRING)
        return toStringListUnchecked();
    else
        return QStringList();
}

QByteArray QDBusDemarshaller::toByteArrayUnchecked()
{
    DBusMessageIter sub;
    q_dbus_message_iter_recurse(&iterator, &sub);
    q_dbus_message_iter_next(&iterator);
    int len;
    char* data;
    q_dbus_message_iter_get_fixed_array(&sub,&data,&len);
    return QByteArray(data,len);
}

QByteArray QDBusDemarshaller::toByteArray()
{
    if (q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_ARRAY
            && q_dbus_message_iter_get_element_type(&iterator) == DBUS_TYPE_BYTE) {
        return toByteArrayUnchecked();
    }
    return QByteArray();
}

bool QDBusDemarshaller::atEnd()
{
    // dbus_message_iter_has_next is broken if the list has one single element
    return q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_INVALID;
}

inline QDBusDemarshaller *QDBusDemarshaller::beginStructure()
{
    return beginCommon();
}

inline QDBusDemarshaller *QDBusDemarshaller::beginArray()
{
    return beginCommon();
}

inline QDBusDemarshaller *QDBusDemarshaller::beginMap()
{
    return beginCommon();
}

inline QDBusDemarshaller *QDBusDemarshaller::beginMapEntry()
{
    return beginCommon();
}

QDBusDemarshaller *QDBusDemarshaller::beginCommon()
{
    QDBusDemarshaller *d = new QDBusDemarshaller(capabilities);
    d->parent = this;
    d->message = q_dbus_message_ref(message);

    // recurse
    q_dbus_message_iter_recurse(&iterator, &d->iterator);
    q_dbus_message_iter_next(&iterator);
    return d;
}

inline QDBusDemarshaller *QDBusDemarshaller::endStructure()
{
    return endCommon();
}

inline QDBusDemarshaller *QDBusDemarshaller::endArray()
{
    return endCommon();
}

inline QDBusDemarshaller *QDBusDemarshaller::endMap()
{
    return endCommon();
}

inline QDBusDemarshaller *QDBusDemarshaller::endMapEntry()
{
    return endCommon();
}

QDBusDemarshaller *QDBusDemarshaller::endCommon()
{
    QDBusDemarshaller *retval = parent;
    delete this;
    return retval;
}

QDBusArgument QDBusDemarshaller::duplicate()
{
    QScopedPointer<QDBusDemarshaller> d(new QDBusDemarshaller(capabilities));
    d->iterator = iterator;
    d->message = q_dbus_message_ref(message);

    q_dbus_message_iter_next(&iterator);
    return QDBusArgumentPrivate::create(d.take());
}

QT_END_NAMESPACE
