/****************************************************************************
**
** 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 "qdbusmetatype_p.h"
#include "qdbusutil_p.h"

#ifndef QT_NO_DBUS

QT_BEGIN_NAMESPACE

static void qIterAppend(DBusMessageIter *it, QByteArray *ba, int type, const void *arg)
{
    if (ba)
        *ba += char(type);
    else
        q_dbus_message_iter_append_basic(it, type, arg);
}

QDBusMarshaller::~QDBusMarshaller()
{
    close();
}

inline QString QDBusMarshaller::currentSignature()
{
    if (message)
        return QString::fromUtf8(q_dbus_message_get_signature(message));
    return QString();
}

inline void QDBusMarshaller::append(uchar arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_BYTE, &arg);
}

inline void QDBusMarshaller::append(bool arg)
{
    dbus_bool_t cast = arg;
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_BOOLEAN, &cast);
}

inline void QDBusMarshaller::append(short arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_INT16, &arg);
}

inline void QDBusMarshaller::append(ushort arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_UINT16, &arg);
}

inline void QDBusMarshaller::append(int arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_INT32, &arg);
}

inline void QDBusMarshaller::append(uint arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_UINT32, &arg);
}

inline void QDBusMarshaller::append(qlonglong arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_INT64, &arg);
}

inline void QDBusMarshaller::append(qulonglong arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_UINT64, &arg);
}

inline void QDBusMarshaller::append(double arg)
{
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_DOUBLE, &arg);
}

void QDBusMarshaller::append(const QString &arg)
{
    QByteArray data = arg.toUtf8();
    const char *cdata = data.constData();
    if (!skipSignature)
        qIterAppend(&iterator, ba, DBUS_TYPE_STRING, &cdata);
}

inline void QDBusMarshaller::append(const QDBusObjectPath &arg)
{
    QByteArray data = arg.path().toUtf8();
    if (!ba && data.isEmpty()) {
        error(QLatin1String("Invalid object path passed in arguments"));
    } else {
        const char *cdata = data.constData();
        if (!skipSignature)
            qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata);
    }
}

inline void QDBusMarshaller::append(const QDBusSignature &arg)
{
    QByteArray data = arg.signature().toUtf8();
    if (!ba && data.isEmpty()) {
        error(QLatin1String("Invalid signature passed in arguments"));
    } else {
        const char *cdata = data.constData();
        if (!skipSignature)
            qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata);
    }
}

inline void QDBusMarshaller::append(const QDBusUnixFileDescriptor &arg)
{
    int fd = arg.fileDescriptor();
    if (!ba && fd == -1) {
        error(QLatin1String("Invalid file descriptor passed in arguments"));
    } else {
        if (!skipSignature)
            qIterAppend(&iterator, ba, DBUS_TYPE_UNIX_FD, &fd);
    }
}

inline void QDBusMarshaller::append(const QByteArray &arg)
{
    if (ba) {
        if (!skipSignature)
            *ba += DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
        return;
    }

    const char* cdata = arg.constData();
    DBusMessageIter subiterator;
    q_dbus_message_iter_open_container(&iterator, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING,
                                     &subiterator);
    q_dbus_message_iter_append_fixed_array(&subiterator, DBUS_TYPE_BYTE, &cdata, arg.length());
    q_dbus_message_iter_close_container(&iterator, &subiterator);
}

inline bool QDBusMarshaller::append(const QDBusVariant &arg)
{
    if (ba) {
        if (!skipSignature)
            *ba += DBUS_TYPE_VARIANT_AS_STRING;
        return true;
    }

    const QVariant &value = arg.variant();
    int id = value.userType();
    if (id == QVariant::Invalid) {
        qWarning("QDBusMarshaller: cannot add a null QDBusVariant");
        error(QLatin1String("Variant containing QVariant::Invalid passed in arguments"));
        return false;
    }

    QByteArray tmpSignature;
    const char *signature = 0;
    if (id == QDBusMetaTypeId::argument()) {
        // take the signature from the QDBusArgument object we're marshalling
        tmpSignature =
            qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1();
        signature = tmpSignature.constData();
    } else {
        // take the signatuer from the metatype we're marshalling
        signature = QDBusMetaType::typeToSignature(id);
    }
    if (!signature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QMetaType::typeName(id), id);
        error(QLatin1String("Unregistered type %1 passed in arguments")
              .arg(QLatin1String(QMetaType::typeName(id))));
        return false;
    }

    QDBusMarshaller sub(capabilities);
    open(sub, DBUS_TYPE_VARIANT, signature);
    bool isOk = sub.appendVariantInternal(value);
    // don't call sub.close(): it auto-closes

    return isOk;
}

inline void QDBusMarshaller::append(const QStringList &arg)
{
    if (ba) {
        if (!skipSignature)
            *ba += DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
        return;
    }

    QDBusMarshaller sub(capabilities);
    open(sub, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING);
    QStringList::ConstIterator it = arg.constBegin();
    QStringList::ConstIterator end = arg.constEnd();
    for ( ; it != end; ++it)
        sub.append(*it);
    // don't call sub.close(): it auto-closes
}

inline QDBusMarshaller *QDBusMarshaller::beginStructure()
{
    return beginCommon(DBUS_TYPE_STRUCT, 0);
}

inline QDBusMarshaller *QDBusMarshaller::beginArray(int id)
{
    const char *signature = QDBusMetaType::typeToSignature( QVariant::Type(id) );
    if (!signature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QMetaType::typeName(id), id);
        error(QLatin1String("Unregistered type %1 passed in arguments")
              .arg(QLatin1String(QMetaType::typeName(id))));
        return this;
    }

    return beginCommon(DBUS_TYPE_ARRAY, signature);
}

inline QDBusMarshaller *QDBusMarshaller::beginMap(int kid, int vid)
{
    const char *ksignature = QDBusMetaType::typeToSignature( QVariant::Type(kid) );
    if (!ksignature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QMetaType::typeName(kid), kid);
        error(QLatin1String("Unregistered type %1 passed in arguments")
              .arg(QLatin1String(QMetaType::typeName(kid))));
        return this;
    }
    if (ksignature[1] != 0 || !QDBusUtil::isValidBasicType(*ksignature)) {
        qWarning("QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-BUS map.",
                 QMetaType::typeName(kid), kid);
        error(QLatin1String("Type %1 passed in arguments cannot be used as a key in a map")
              .arg(QLatin1String(QMetaType::typeName(kid))));
        return this;
    }

    const char *vsignature = QDBusMetaType::typeToSignature( QVariant::Type(vid) );
    if (!vsignature) {
        const char *typeName = QMetaType::typeName(vid);
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 typeName, vid);
        error(QLatin1String("Unregistered type %1 passed in arguments")
              .arg(QLatin1String(typeName)));
        return this;
    }

    QByteArray signature;
    signature = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
    signature += ksignature;
    signature += vsignature;
    signature += DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
    return beginCommon(DBUS_TYPE_ARRAY, signature);
}

inline QDBusMarshaller *QDBusMarshaller::beginMapEntry()
{
    return beginCommon(DBUS_TYPE_DICT_ENTRY, 0);
}

void QDBusMarshaller::open(QDBusMarshaller &sub, int code, const char *signature)
{
    sub.parent = this;
    sub.ba = ba;
    sub.ok = true;
    sub.capabilities = capabilities;
    sub.skipSignature = skipSignature;

    if (ba) {
        if (!skipSignature) {
            switch (code) {
            case DBUS_TYPE_ARRAY:
                *ba += char(code);
                *ba += signature;
                Q_FALLTHROUGH();

            case DBUS_TYPE_DICT_ENTRY:
                sub.closeCode = 0;
                sub.skipSignature = true;
                break;

            case DBUS_TYPE_STRUCT:
                *ba += DBUS_STRUCT_BEGIN_CHAR;
                sub.closeCode = DBUS_STRUCT_END_CHAR;
                break;
            }
        }
    } else {
        q_dbus_message_iter_open_container(&iterator, code, signature, &sub.iterator);
    }
}

QDBusMarshaller *QDBusMarshaller::beginCommon(int code, const char *signature)
{
    QDBusMarshaller *d = new QDBusMarshaller(capabilities);
    open(*d, code, signature);
    return d;
}

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

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

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

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

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

void QDBusMarshaller::close()
{
    if (ba) {
        if (!skipSignature && closeCode)
            *ba += closeCode;
    } else if (parent) {
        q_dbus_message_iter_close_container(&parent->iterator, &iterator);
    }
}

void QDBusMarshaller::error(const QString &msg)
{
    ok = false;
    if (parent)
        parent->error(msg);
    else
        errorString = msg;
}

bool QDBusMarshaller::appendVariantInternal(const QVariant &arg)
{
    int id = arg.userType();
    if (id == QVariant::Invalid) {
        qWarning("QDBusMarshaller: cannot add an invalid QVariant");
        error(QLatin1String("Variant containing QVariant::Invalid passed in arguments"));
        return false;
    }

    // intercept QDBusArgument parameters here
    if (id == QDBusMetaTypeId::argument()) {
        QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg);
        QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument);
        if (!d->message)
            return false;       // can't append this one...

        QDBusDemarshaller demarshaller(capabilities);
        demarshaller.message = q_dbus_message_ref(d->message);

        if (d->direction == Demarshalling) {
            // it's demarshalling; just copy
            demarshaller.iterator = static_cast<QDBusDemarshaller *>(d)->iterator;
        } else {
            // it's marshalling; start over
            if (!q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
                return false;   // error!
        }

        return appendCrossMarshalling(&demarshaller);
    }

    const char *signature = QDBusMetaType::typeToSignature( QVariant::Type(id) );
    if (!signature) {
        qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. "
                 "Use qDBusRegisterMetaType to register it",
                 QMetaType::typeName(id), id);
        error(QLatin1String("Unregistered type %1 passed in arguments")
              .arg(QLatin1String(QMetaType::typeName(id))));
        return false;
    }

    switch (*signature) {
#ifdef __OPTIMIZE__
    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_DOUBLE:
        qIterAppend(&iterator, ba, *signature, arg.constData());
        return true;
    case DBUS_TYPE_BOOLEAN:
        append( arg.toBool() );
        return true;
#else
    case DBUS_TYPE_BYTE:
        append( qvariant_cast<uchar>(arg) );
        return true;
    case DBUS_TYPE_BOOLEAN:
        append( arg.toBool() );
        return true;
    case DBUS_TYPE_INT16:
        append( qvariant_cast<short>(arg) );
        return true;
    case DBUS_TYPE_UINT16:
        append( qvariant_cast<ushort>(arg) );
        return true;
    case DBUS_TYPE_INT32:
        append( static_cast<dbus_int32_t>(arg.toInt()) );
        return true;
    case DBUS_TYPE_UINT32:
        append( static_cast<dbus_uint32_t>(arg.toUInt()) );
        return true;
    case DBUS_TYPE_INT64:
        append( arg.toLongLong() );
        return true;
    case DBUS_TYPE_UINT64:
        append( arg.toULongLong() );
        return true;
    case DBUS_TYPE_DOUBLE:
        append( arg.toDouble() );
        return true;
#endif

    case DBUS_TYPE_STRING:
        append( arg.toString() );
        return true;
    case DBUS_TYPE_OBJECT_PATH:
        append( qvariant_cast<QDBusObjectPath>(arg) );
        return true;
    case DBUS_TYPE_SIGNATURE:
        append( qvariant_cast<QDBusSignature>(arg) );
        return true;

    // compound types:
    case DBUS_TYPE_VARIANT:
        // nested QVariant
        return append( qvariant_cast<QDBusVariant>(arg) );

    case DBUS_TYPE_ARRAY:
        // could be many things
        // find out what kind of array it is
        switch (arg.type()) {
        case QVariant::StringList:
            append( arg.toStringList() );
            return true;

        case QVariant::ByteArray:
            append( arg.toByteArray() );
            return true;

        default:
            ;
        }
        Q_FALLTHROUGH();

    case DBUS_TYPE_STRUCT:
    case DBUS_STRUCT_BEGIN_CHAR:
        return appendRegisteredType( arg );

    case DBUS_TYPE_DICT_ENTRY:
    case DBUS_DICT_ENTRY_BEGIN_CHAR:
        qFatal("QDBusMarshaller::appendVariantInternal got a DICT_ENTRY!");
        return false;

    case DBUS_TYPE_UNIX_FD:
        if (capabilities & QDBusConnection::UnixFileDescriptorPassing || ba) {
            append(qvariant_cast<QDBusUnixFileDescriptor>(arg));
            return true;
        }
        Q_FALLTHROUGH();

    default:
        qWarning("QDBusMarshaller::appendVariantInternal: Found unknown D-BUS type '%s'",
                 signature);
        return false;
    }

    return true;
}

bool QDBusMarshaller::appendRegisteredType(const QVariant &arg)
{
    ref.ref();                  // reference up
    QDBusArgument self(QDBusArgumentPrivate::create(this));
    return QDBusMetaType::marshall(self, arg.userType(), arg.constData());
}

bool QDBusMarshaller::appendCrossMarshalling(QDBusDemarshaller *demarshaller)
{
    int code = q_dbus_message_iter_get_arg_type(&demarshaller->iterator);
    if (QDBusUtil::isValidBasicType(code)) {
        // easy: just append
        // do exactly like the D-BUS docs suggest
        // (see apidocs for q_dbus_message_iter_get_basic)

        qlonglong value;
        q_dbus_message_iter_get_basic(&demarshaller->iterator, &value);
        q_dbus_message_iter_next(&demarshaller->iterator);
        q_dbus_message_iter_append_basic(&iterator, code, &value);
        return true;
    }

    if (code == DBUS_TYPE_ARRAY) {
        int element = q_dbus_message_iter_get_element_type(&demarshaller->iterator);
        if (QDBusUtil::isValidFixedType(element) && element != DBUS_TYPE_UNIX_FD) {
            // another optimization: fixed size arrays
            // code is exactly like QDBusDemarshaller::toByteArray
            DBusMessageIter sub;
            q_dbus_message_iter_recurse(&demarshaller->iterator, &sub);
            q_dbus_message_iter_next(&demarshaller->iterator);
            int len;
            void* data;
            q_dbus_message_iter_get_fixed_array(&sub,&data,&len);

            char signature[2] = { char(element), 0 };
            q_dbus_message_iter_open_container(&iterator, DBUS_TYPE_ARRAY, signature, &sub);
            q_dbus_message_iter_append_fixed_array(&sub, element, &data, len);
            q_dbus_message_iter_close_container(&iterator, &sub);

            return true;
        }
    }

    // We have to recurse
    QDBusDemarshaller *drecursed = demarshaller->beginCommon();

    QDBusMarshaller mrecursed(capabilities);  // create on the stack makes it autoclose
    QByteArray subSignature;
    const char *sig = 0;
    if (code == DBUS_TYPE_VARIANT || code == DBUS_TYPE_ARRAY) {
        subSignature = drecursed->currentSignature().toLatin1();
        if (!subSignature.isEmpty())
            sig = subSignature.constData();
    }
    open(mrecursed, code, sig);

    while (!drecursed->atEnd()) {
        if (!mrecursed.appendCrossMarshalling(drecursed)) {
            delete drecursed;
            return false;
        }
    }

    delete drecursed;
    return true;
}

QT_END_NAMESPACE

#endif // QT_NO_DBUS
