/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QDebug>
#include <QtCore>
#include <poll.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <glib.h>
#include "dbusdispatcher.h"

namespace Maemo {

/*!
    \class Maemo::DBusDispatcher

    \brief DBusDispatcher is a class that can send DBUS method call
    messages and receive unicast signals from DBUS objects.
*/

class DBusDispatcherPrivate
{
public:
    DBusDispatcherPrivate(const QString& service,
                          const QString& path,
                          const QString& interface,
                          const QString& signalPath)
        : service(service), path(path), interface(interface),
          signalPath(signalPath), connection(0)
    {
        memset(&signal_vtable, 0, sizeof(signal_vtable));
    }

    ~DBusDispatcherPrivate()
    {
        foreach(DBusPendingCall *call, pending_calls) {
            dbus_pending_call_cancel(call);
            dbus_pending_call_unref(call);
        }
    }

    QString service;
    QString path;
    QString interface;
    QString signalPath;
    struct DBusConnection *connection;
    QList<DBusPendingCall *> pending_calls;
    struct DBusObjectPathVTable signal_vtable;
};

static bool constantVariantList(const QVariantList& variantList) {
    // Special case, empty list == empty struct
    if (variantList.isEmpty()) {
        return false;
    } else {        
        QVariant::Type type = variantList[0].type();
        // Iterate items in the list and check if they are same type
        foreach(QVariant variant, variantList) {
            if (variant.type() != type) {
                return false;
            }
        }
    }
    return true;
}

static QString variantToSignature(const QVariant& argument,
                                  bool constantList = true) {
    switch (argument.type()) {
        case QVariant::Bool:
            return "b";
        case QVariant::ByteArray:
            return "ay";
        case QVariant::Char:
            return "y";
        case QVariant::Int:
            return "i";
        case QVariant::UInt:
            return "u";
        case QVariant::StringList:
            return "as";
        case QVariant::String:
            return "s";
        case QVariant::LongLong:
            return "x";
        case QVariant::ULongLong:
            return "t";
        case QVariant::List:
            {
            QString signature;
            QVariantList variantList = argument.toList();
            if (!constantList) {
                signature += DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
                foreach(QVariant listItem, variantList) {
                    signature += variantToSignature(listItem);
                }
                signature += DBUS_STRUCT_END_CHAR_AS_STRING;
            } else {
                if (variantList.isEmpty())
                    return "";
                signature = "a" + variantToSignature(variantList[0]);
            }

            return signature;
            }
        default:
            qDebug() << "Unsupported variant type: " << argument.type();
            break;
    }

    return "";
}

static bool appendVariantToDBusMessage(const QVariant& argument,
                                       DBusMessageIter *dbus_iter) {
    int idx = 0;
    DBusMessageIter array_iter;
    QStringList str_list;
    dbus_bool_t bool_data;
    dbus_int32_t int32_data;
    dbus_uint32_t uint32_data;
    dbus_int64_t int64_data;
    dbus_uint64_t uint64_data;
    char *str_data;
    char char_data;

    switch (argument.type()) {

        case QVariant::Bool:
            bool_data = argument.toBool();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_BOOLEAN, 
                                           &bool_data);
            break;

        case QVariant::ByteArray:
            str_data = argument.toByteArray().data();
            dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
                                             DBUS_TYPE_BYTE_AS_STRING, &array_iter);
            dbus_message_iter_append_fixed_array(&array_iter,
                                                 DBUS_TYPE_BYTE,
                                                 &str_data,
                                                 argument.toByteArray().size());
            dbus_message_iter_close_container(dbus_iter, &array_iter);
            break;

        case QVariant::Char:
            char_data = argument.toChar().toAscii();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_BYTE, 
                                           &char_data);
            break;

        case QVariant::Int:
            int32_data = argument.toInt();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_INT32, 
                                           &int32_data);
            break;

        case QVariant::String: {
            QByteArray data = argument.toString().toUtf8();
            str_data = data.data();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_STRING,
                                           &str_data);
            break;
        }

        case QVariant::StringList:
            str_list = argument.toStringList();
            dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
                                             "s", &array_iter);
            for (idx = 0; idx < str_list.size(); idx++) {
                QByteArray data = str_list.at(idx).toLatin1();
                str_data = data.data();
                dbus_message_iter_append_basic(&array_iter,
                                               DBUS_TYPE_STRING,
                                               &str_data);
            }
            dbus_message_iter_close_container(dbus_iter, &array_iter);
            break;

        case QVariant::UInt:
            uint32_data = argument.toUInt();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_UINT32, 
                                           &uint32_data);
            break;

        case QVariant::ULongLong:
            uint64_data = argument.toULongLong();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_UINT64, 
                                           &uint64_data);
            break;

        case QVariant::LongLong:
            int64_data = argument.toLongLong();
            dbus_message_iter_append_basic(dbus_iter, DBUS_TYPE_INT64, 
                                           &int64_data);
            break;

        case QVariant::List:
            {
            QVariantList variantList = argument.toList();
            bool constantList = constantVariantList(variantList);
            DBusMessageIter array_iter;

            // List is mapped either as an DBUS array (all items same type)
            // DBUS struct (variable types) depending on constantList
            if (constantList) {
                // Resolve the signature for the first item
                QString signature = "";
                if (!variantList.isEmpty()) {
                    signature = variantToSignature(
                                variantList[0],
                                constantVariantList(variantList[0].toList()));
                }

                // Mapped as DBUS array
                dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_ARRAY,
                                                 signature.toAscii(),
                                                 &array_iter);

                foreach(QVariant listItem, variantList) {
                    appendVariantToDBusMessage(listItem, &array_iter);
                }

                dbus_message_iter_close_container(dbus_iter, &array_iter);
            } else {
                // Mapped as DBUS struct
                dbus_message_iter_open_container(dbus_iter, DBUS_TYPE_STRUCT,
                                                 NULL,
                                                 &array_iter);

                foreach(QVariant listItem, variantList) {
                    appendVariantToDBusMessage(listItem, &array_iter);
                }

                dbus_message_iter_close_container(dbus_iter, &array_iter);
            }

            break;
            }
        default:
            qDebug() << "Unsupported variant type: " << argument.type();
            break;
    }

    return true;
}

static QVariant getVariantFromDBusMessage(DBusMessageIter *iter) {
    dbus_bool_t bool_data;
    dbus_int32_t int32_data;
    dbus_uint32_t uint32_data;
    dbus_int64_t int64_data;
    dbus_uint64_t uint64_data;
    char *str_data;
    char char_data;
    int argtype = dbus_message_iter_get_arg_type(iter);

    switch (argtype) {

        case DBUS_TYPE_BOOLEAN:
        {
            dbus_message_iter_get_basic(iter, &bool_data);
            QVariant variant((bool)bool_data);
            return variant;
        }

        case DBUS_TYPE_ARRAY:
        {
            // Handle all arrays here
            int elem_type = dbus_message_iter_get_element_type(iter);
            DBusMessageIter array_iter;

            dbus_message_iter_recurse(iter, &array_iter);

            if (elem_type == DBUS_TYPE_BYTE) {
                QByteArray byte_array;
                do {
                    dbus_message_iter_get_basic(&array_iter, &char_data);
                    byte_array.append(char_data);
                } while (dbus_message_iter_next(&array_iter));
                QVariant variant(byte_array);
                return variant;
            } else if (elem_type == DBUS_TYPE_STRING) {
                QStringList str_list;
                do {
                    dbus_message_iter_get_basic(&array_iter, &str_data);
                    str_list.append(str_data);
                } while (dbus_message_iter_next(&array_iter));
                QVariant variant(str_list);
                return variant;
            } else {
                QVariantList variantList;
                do {
                    variantList << getVariantFromDBusMessage(&array_iter);
                } while (dbus_message_iter_next(&array_iter));
                QVariant variant(variantList);
                return variant;
            }
            break;
        }

        case DBUS_TYPE_BYTE:
        {
            dbus_message_iter_get_basic(iter, &char_data);
            QChar ch(char_data);
            QVariant variant(ch);
            return variant;
        }

        case DBUS_TYPE_INT32:
        {
            dbus_message_iter_get_basic(iter, &int32_data);
            QVariant variant((int)int32_data);
            return variant;
        }

        case DBUS_TYPE_UINT32:
        {
            dbus_message_iter_get_basic(iter, &uint32_data);
            QVariant variant((uint)uint32_data);
            return variant;
        }

        case DBUS_TYPE_STRING:
        {
            dbus_message_iter_get_basic(iter, &str_data);
            QString str(QString::fromUtf8(str_data));
            QVariant variant(str);
            return variant;
        }

        case DBUS_TYPE_INT64:
        {
            dbus_message_iter_get_basic(iter, &int64_data);
            QVariant variant((qlonglong)int64_data);
            return variant;
        }

        case DBUS_TYPE_UINT64:
        {
            dbus_message_iter_get_basic(iter, &uint64_data);
            QVariant variant((qulonglong)uint64_data);
            return variant;
        }

        case DBUS_TYPE_STRUCT:
        {
            // Handle all structs here
            DBusMessageIter struct_iter;
            dbus_message_iter_recurse(iter, &struct_iter);

	    QVariantList variantList;
	    do {
	      variantList << getVariantFromDBusMessage(&struct_iter);
	    } while (dbus_message_iter_next(&struct_iter));
	    QVariant variant(variantList);
	    return variant;
        }

        default:
            qDebug() << "Unsupported DBUS type: " << argtype;
    }

    return QVariant();
}

static DBusHandlerResult signalHandler (DBusConnection *connection,
                                        DBusMessage *message,
                                        void *object_ref) {
    (void)connection;
    QString interface;
    QString signal;
    DBusDispatcher *dispatcher = (DBusDispatcher *)object_ref;

    if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) {
        interface = dbus_message_get_interface(message);
        signal = dbus_message_get_member(message);
        
        QList<QVariant> arglist;
        DBusMessageIter dbus_iter;

        if (dbus_message_iter_init(message, &dbus_iter)) {
            // Read return arguments
            while (dbus_message_iter_get_arg_type (&dbus_iter) != DBUS_TYPE_INVALID) {
                arglist << getVariantFromDBusMessage(&dbus_iter);
                dbus_message_iter_next(&dbus_iter);
            }
        }

        dispatcher->emitSignalReceived(interface, signal, arglist);
        return DBUS_HANDLER_RESULT_HANDLED;
    }
    (void)message;
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

DBusDispatcher::DBusDispatcher(const QString& service,
                               const QString& path,
                               const QString& interface,
                               QObject *parent)
 : QObject(parent),
   d_ptr(new DBusDispatcherPrivate(service, path, interface, path)) {
    setupDBus();
}

DBusDispatcher::DBusDispatcher(const QString& service,
                               const QString& path,
                               const QString& interface,
                               const QString& signalPath,
                               QObject *parent)
 : QObject(parent),
   d_ptr(new DBusDispatcherPrivate(service, path, interface, signalPath)) {
    setupDBus();
}

DBusDispatcher::~DBusDispatcher()
{
    if (d_ptr->connection) {
        dbus_connection_close(d_ptr->connection);
        dbus_connection_unref(d_ptr->connection);
    }
    delete d_ptr;
}

void DBusDispatcher::setupDBus()
{
    d_ptr->connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);

    if (d_ptr->connection == NULL)
        qDebug() << "Unable to get DBUS connection!";
    else {
        d_ptr->signal_vtable.message_function = signalHandler;

	dbus_connection_set_exit_on_disconnect(d_ptr->connection, FALSE);
        dbus_connection_setup_with_g_main(d_ptr->connection, g_main_context_get_thread_default());
        dbus_connection_register_object_path(d_ptr->connection, 
                                             d_ptr->signalPath.toLatin1(),
                                             &d_ptr->signal_vtable,
                                             this);
    }
}

static DBusMessage *prepareDBusCall(const QString& service,
                                    const QString& path,
                                    const QString& interface,
                                    const QString& method, 
                                    const QVariant& arg1 = QVariant(),
                                    const QVariant& arg2 = QVariant(),
                                    const QVariant& arg3 = QVariant(),
                                    const QVariant& arg4 = QVariant(),
                                    const QVariant& arg5 = QVariant(),
                                    const QVariant& arg6 = QVariant(),
                                    const QVariant& arg7 = QVariant(),
                                    const QVariant& arg8 = QVariant()) 
{
    DBusMessage *message = dbus_message_new_method_call(service.toLatin1(),
                                                        path.toLatin1(),
                                                        interface.toLatin1(),
                                                        method.toLatin1());
    DBusMessageIter dbus_iter;

    // Append variants to DBUS message
    QList<QVariant> arglist;
    if (arg1.isValid()) arglist << arg1;
    if (arg2.isValid()) arglist << arg2;
    if (arg3.isValid()) arglist << arg3;
    if (arg4.isValid()) arglist << arg4;
    if (arg5.isValid()) arglist << arg5;
    if (arg6.isValid()) arglist << arg6;
    if (arg7.isValid()) arglist << arg7;
    if (arg8.isValid()) arglist << arg8;

    dbus_message_iter_init_append (message, &dbus_iter);
    
    while (!arglist.isEmpty()) {
        QVariant argument = arglist.takeFirst();
        appendVariantToDBusMessage(argument, &dbus_iter);
    }

    return message;
}

QList<QVariant> DBusDispatcher::call(const QString& method, 
                                     const QVariant& arg1,
                                     const QVariant& arg2,
                                     const QVariant& arg3,
                                     const QVariant& arg4,
                                     const QVariant& arg5,
                                     const QVariant& arg6,
                                     const QVariant& arg7,
                                     const QVariant& arg8) {
    DBusMessageIter dbus_iter;
    DBusMessage *message = prepareDBusCall(d_ptr->service, d_ptr->path,
                                           d_ptr->interface, method,
                                           arg1, arg2, arg3, arg4, arg5,
                                           arg6, arg7, arg8);
    DBusMessage *reply = dbus_connection_send_with_reply_and_block(
                                                    d_ptr->connection,
                                                    message, -1, NULL);
    dbus_message_unref(message);

    QList<QVariant> replylist;
    if (reply != NULL &&  dbus_message_iter_init(reply, &dbus_iter)) {
        // Read return arguments
        while (dbus_message_iter_get_arg_type (&dbus_iter) != DBUS_TYPE_INVALID) {
            replylist << getVariantFromDBusMessage(&dbus_iter);
            dbus_message_iter_next(&dbus_iter);
        }
    }
    if (reply != NULL) dbus_message_unref(reply);
    return replylist;
}

class PendingCallInfo {
public:
    QString method;
    DBusDispatcher *dispatcher;
    DBusDispatcherPrivate *priv;
};

static void freePendingCallInfo(void *memory) {
    PendingCallInfo *info = (PendingCallInfo *)memory;
    delete info;
}

static void pendingCallFunction (DBusPendingCall *pending,
                                 void *memory) {
    PendingCallInfo *info = (PendingCallInfo *)memory;
    QString errorStr;
    QList<QVariant> replyList;
    DBusMessage *reply = dbus_pending_call_steal_reply (pending);

    Q_ASSERT(reply != NULL);

    if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
        errorStr = dbus_message_get_error_name (reply);
    } else {
        DBusMessageIter dbus_iter;
        dbus_message_iter_init(reply, &dbus_iter);
        // Read return arguments
        while (dbus_message_iter_get_arg_type (&dbus_iter) != DBUS_TYPE_INVALID) {
            replyList << getVariantFromDBusMessage(&dbus_iter);
            dbus_message_iter_next(&dbus_iter);
        }
    }

    info->priv->pending_calls.removeOne(pending);
    info->dispatcher->emitCallReply(info->method, replyList, errorStr);
    dbus_message_unref(reply);
    dbus_pending_call_unref(pending);
}

bool DBusDispatcher::callAsynchronous(const QString& method, 
                                      const QVariant& arg1,
                                      const QVariant& arg2,
                                      const QVariant& arg3,
                                      const QVariant& arg4,
                                      const QVariant& arg5,
                                      const QVariant& arg6,
                                      const QVariant& arg7,
                                      const QVariant& arg8) {
    DBusMessage *message = prepareDBusCall(d_ptr->service, d_ptr->path,
                                           d_ptr->interface, method,
                                           arg1, arg2, arg3, arg4, arg5,
                                           arg6, arg7, arg8);
    DBusPendingCall *call = NULL;
    dbus_bool_t ret = dbus_connection_send_with_reply(d_ptr->connection,
                                                      message, &call, -1);
    PendingCallInfo *info = new PendingCallInfo;
    info->method = method;
    info->dispatcher = this;
    info->priv = d_ptr;

    dbus_pending_call_set_notify(call, pendingCallFunction, info, freePendingCallInfo);
    d_ptr->pending_calls.append(call);
    return (bool)ret;
}

void DBusDispatcher::emitSignalReceived(const QString& interface, 
                                        const QString& signal,
                                        const QList<QVariant>& args) {
    emit signalReceived(interface, signal, args); }

void DBusDispatcher::emitCallReply(const QString& method,
                                   const QList<QVariant>& args,
                                   const QString& error) {
    emit callReply(method, args, error); }

void DBusDispatcher::synchronousDispatch(int timeout_ms)
{
    dbus_connection_read_write_dispatch(d_ptr->connection, timeout_ms);
}

} // Maemo namespace

