/****************************************************************************
**
** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore 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 "qppsobject_p.h"

#include "qppsobjectprivate_p.h"
#include "qppsattribute_p.h"
#include "qppsattributeprivate_p.h"
#include "qcore_unix_p.h"

#include <QObject>
#include <QSocketNotifier>

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <confname.h>

#include <sys/pps.h>

QT_BEGIN_NAMESPACE

///////////////////////////////////////////////////////////////////////////////
static inline void safeAssign(bool *pointer, bool value)
{
    if (pointer)
        *pointer = value;
}

class QPpsMaxSize
{
public:
    QPpsMaxSize()
    {
        int fd = qt_safe_open("/pps/.all", O_RDONLY);
        if (fd == -1) {
            qWarning("qppsobject.cpp: qt_safe_open failed");
            value = -1;
        }

        // This tells us the maximum transfer size across PPS
        value = ::fpathconf(fd, _PC_REC_MAX_XFER_SIZE);

        qt_safe_close(fd);
    }

    int value;
};

Q_GLOBAL_STATIC(QPpsMaxSize, ppsMaxSize)


///////////////////////////////////////////////////////////////////////////////
//
// QPpsObjectPrivate
//
///////////////////////////////////////////////////////////////////////////////

QPpsObjectPrivate::QPpsObjectPrivate(const QString &path)
    : notifier(0),
      path(path),
      error(EOK),
      fd(-1),
      readyReadEnabled(true)
{
}

QPpsAttributeMap QPpsObjectPrivate::decode(const QByteArray &rawData, bool *ok)
{
    QPpsAttributeMap attributeMap;
    pps_decoder_t decoder;

    QByteArray mutableData(rawData);
    pps_decoder_error_t error = pps_decoder_initialize(&decoder, mutableData.data());
    if (error == PPS_DECODER_OK) {
        // no need to check ok in this case
        attributeMap = decodeObject(&decoder, ok);
    } else {
        qWarning("QPpsObjectPrivate::decode: pps_decoder_initialize failed");
        *ok = false;
    }

    pps_decoder_cleanup(&decoder);
    return attributeMap;
}

QVariantMap QPpsObjectPrivate::variantMapFromPpsAttributeMap(const QPpsAttributeMap &data)
{
    QVariantMap variantMap;

    for (QPpsAttributeMap::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) {
        QVariant variant = variantFromPpsAttribute(it.value());
        if (!variant.isValid())
            return QVariantMap();
        variantMap[it.key()] = variant;
    }

    return variantMap;
}

QPpsAttribute::Flags QPpsObjectPrivate::readFlags(pps_decoder_t *decoder)
{
    int rawFlags = pps_decoder_flags(decoder, 0);

    QPpsAttribute::Flags attributeFlags;

    if (rawFlags & PPS_INCOMPLETE)
        attributeFlags |= QPpsAttribute::Incomplete;
    if (rawFlags & PPS_DELETED)
        attributeFlags |= QPpsAttribute::Deleted;
    if (rawFlags & PPS_CREATED)
        attributeFlags |= QPpsAttribute::Created;
    if (rawFlags & PPS_TRUNCATED)
        attributeFlags |= QPpsAttribute::Truncated;
    if (rawFlags & PPS_PURGED)
        attributeFlags |= QPpsAttribute::Purged;

    return attributeFlags;
}

QPpsAttribute QPpsObjectPrivate::decodeString(pps_decoder_t *decoder)
{
    const char *value = 0;
    pps_decoder_error_t error = pps_decoder_get_string(decoder, 0, &value);

    if (error != PPS_DECODER_OK) {
        qWarning("QPpsObjectPrivate::decodeString: PPS_DECODER_GET_STRING failed");
        return QPpsAttribute();
    }

    QPpsAttribute::Flags flags = readFlags(decoder);
    return QPpsAttributePrivate::createPpsAttribute(QString::fromUtf8(value), flags);
}

QPpsAttribute QPpsObjectPrivate::decodeNumber(pps_decoder_t *decoder)
{
    // In order to support more number types, we have to do something stupid because the PPS
    // library won't let us work any other way. Basically, we have to probe the encoded type in
    // order to try to get exactly what we want.
    int64_t llValue;
    double dValue;
    int iValue;
    QPpsAttribute::Flags flags;

    if (pps_decoder_is_integer(decoder, 0)) {
        pps_decoder_error_t error = pps_decoder_get_int(decoder, 0, &iValue);
        switch (error) {
        case PPS_DECODER_OK:
            flags = readFlags(decoder);
            return QPpsAttributePrivate::createPpsAttribute(iValue, flags);
        case PPS_DECODER_CONVERSION_FAILED:
            error = pps_decoder_get_int64(decoder, 0, &llValue);
            if (error != PPS_DECODER_OK) {
                qWarning("QPpsObjectPrivate::decodeNumber: failed to decode integer");
                return QPpsAttribute();
            }
            flags = readFlags(decoder);
            return QPpsAttributePrivate::createPpsAttribute(static_cast<long long>(llValue), flags);
        default:
            qWarning("QPpsObjectPrivate::decodeNumber: pps_decoder_get_int failed");
            return QPpsAttribute();
        }
    } else {
        pps_decoder_error_t error = pps_decoder_get_double(decoder, 0, &dValue);
        if (error != PPS_DECODER_OK) {
            qWarning("QPpsObjectPrivate::decodeNumber: pps_decoder_get_double failed");
            return QPpsAttribute();
        }
        flags = readFlags(decoder);
        return QPpsAttributePrivate::createPpsAttribute(dValue, flags);
    }
}

QPpsAttribute QPpsObjectPrivate::decodeBool(pps_decoder_t *decoder)
{
    bool value;
    pps_decoder_error_t error = pps_decoder_get_bool(decoder, 0, &value);

    if (error != PPS_DECODER_OK) {
        qWarning("QPpsObjectPrivate::decodeBool: pps_decoder_get_bool failed");
        return QPpsAttribute();
    }

    QPpsAttribute::Flags flags = readFlags(decoder);
    return QPpsAttributePrivate::createPpsAttribute(value, flags);
}

template<typename T>
QPpsAttribute QPpsObjectPrivate::decodeNestedData(T (*decodeFunction)(pps_decoder_t *, bool *),
                                                  pps_decoder_t *decoder)
{
    // We must read the flags before we push into the object,
    // otherwise we'll get the flags for the first element in the object.
    QPpsAttribute::Flags flags = readFlags(decoder);

    if (!decoderPush(decoder))
        return QPpsAttribute();

    bool ok = false;

    T attributeContainer = decodeFunction(decoder, &ok);

    if (!ok)
        return QPpsAttribute();

    QPpsAttribute returnVal = QPpsAttributePrivate::createPpsAttribute(attributeContainer, flags);

    if (!decoderPop(decoder))
        return QPpsAttribute();

    return returnVal;
}

QPpsAttribute QPpsObjectPrivate::decodeData(pps_decoder_t *decoder)
{
    pps_node_type_t nodeType = pps_decoder_type(decoder, 0);
    switch (nodeType) {
    case PPS_TYPE_BOOL:
        return decodeBool(decoder);
    case PPS_TYPE_NUMBER:
        return decodeNumber(decoder);
    case PPS_TYPE_STRING:
        return decodeString(decoder);
    case PPS_TYPE_ARRAY:
        return decodeNestedData(&QPpsObjectPrivate::decodeArray, decoder);
    case PPS_TYPE_OBJECT:
        return decodeNestedData(&QPpsObjectPrivate::decodeObject, decoder);
    case PPS_TYPE_DELETED: {
        // This should create an attribute with the flags set to PpsAttribute::Deleted.
        // However, we need to create a valid QPpsAttribute while doing so. To do this,
        // I'll create an empty map as a sentinel. Note that the readFlags() call with produce
        // the correct set of flags. While I suspect that there will never be any other flags
        // set in conjunction with this one, I'd rather not be surprised later.
        QPpsAttributeMap emptyMap;
        QPpsAttribute::Flags flags = readFlags(decoder);
        QPpsAttribute returnVal = QPpsAttributePrivate::createPpsAttribute(emptyMap, flags);
        return returnVal;
    }
    case PPS_TYPE_NULL:
    case PPS_TYPE_NONE:
    case PPS_TYPE_UNKNOWN:
    default:
        qWarning("QPpsObjectPrivate::decodeData: invalid pps_node_type");
        return QPpsAttribute();
    }
}

QPpsAttributeList QPpsObjectPrivate::decodeArray(pps_decoder_t *decoder, bool *ok)
{
    QPpsAttributeList list;

    int length = pps_decoder_length(decoder);
    for (int i = 0; i < length; ++i) {
        // Force movement to a specific index.
        pps_decoder_error_t error = pps_decoder_goto_index(decoder, i);
        if (error != PPS_DECODER_OK) {
            qWarning("QPpsObjectPrivate::decodeArray: pps_decoder_goto_index failed");
            *ok = false;
            return QPpsAttributeList();
        }

        QPpsAttribute ppsAttribute = decodeData(decoder);
        if (!ppsAttribute.isValid()) {
            *ok = false;
            return QPpsAttributeList();
        }

        list << ppsAttribute;
    }

    *ok = true;
    return list;
}

QPpsAttributeMap QPpsObjectPrivate::decodeObject(pps_decoder_t *decoder, bool *ok)
{
    QPpsAttributeMap map;

    int length = pps_decoder_length(decoder);
    for (int i = 0; i < length; ++i) {
        // Force movement to a specific index.
        pps_decoder_error_t error = pps_decoder_goto_index(decoder, i);
        if (error != PPS_DECODER_OK) {
            qWarning("QPpsObjectPrivate::decodeObject: pps_decoder_goto_index failed");
            *ok = false;
            return QPpsAttributeMap();
        }
        QString name = QString::fromUtf8(pps_decoder_name(decoder));
        QPpsAttribute ppsAttribute = decodeData(decoder);
        if (!ppsAttribute.isValid()) {
            *ok = false;
            return QPpsAttributeMap();
        }
        map[name] = ppsAttribute;
    }

    *ok = true;
    return map;
}

QVariant QPpsObjectPrivate::variantFromPpsAttribute(const QPpsAttribute &attribute)
{
    switch (attribute.type()) {
    case QPpsAttribute::Number:
        switch (attribute.toVariant().type()) {
        case QVariant::Int:
            return attribute.toInt();
        case QVariant::LongLong:
            return attribute.toLongLong();
        default:
            return attribute.toDouble();
        }
        break;
    case QPpsAttribute::Bool:
        return attribute.toBool();
    case QPpsAttribute::String:
        return attribute.toString();
    case QPpsAttribute::Array: {
        QVariantList variantList;
        const auto attrs = attribute.toList();
        for (const QPpsAttribute &attr : attrs) {
            QVariant variant = variantFromPpsAttribute(attr);
            if (!variant.isValid())
                return QVariantList();
            variantList << variant;
        }
        return variantList;
    }
    case QPpsAttribute::Object:
        return variantMapFromPpsAttributeMap(attribute.toMap());
    case QPpsAttribute::None:
    default:
        qWarning("QPpsObjectPrivate::variantFromPpsAttribute: invalid attribute parameter");
        return QVariant();
    }
}

QByteArray QPpsObjectPrivate::encode(const QVariantMap &ppsData, bool *ok)
{
    pps_encoder_t encoder;
    pps_encoder_initialize(&encoder, false);

    encodeObject(&encoder, ppsData, ok);
    const char *rawData = 0;
    if (*ok) {
        // rawData points to a memory owned by encoder.
        // The memory will be freed when pps_encoder_cleanup is called.
        rawData = pps_encoder_buffer(&encoder);
        if (!rawData) {
            qWarning("QPpsObjectPrivate::encode: pps_encoder_buffer failed");
            *ok = false;
        }
    }

    pps_encoder_cleanup(&encoder);
    return QByteArray(rawData);
}

void QPpsObjectPrivate::encodeData(pps_encoder_t *encoder, const char *name, const QVariant &data,
                                   bool *ok)
{
    const char *errorFunction;
    pps_encoder_error_t error = PPS_ENCODER_OK;
    switch (data.type()) {
    case QVariant::Bool:
        error = pps_encoder_add_bool(encoder, name, data.toBool());
        errorFunction = "pps_encoder_add_bool";
        break;
    // We want to support encoding uint even though libpps doesn't support it directly.
    // We can't encode uint as an int since that will lose precision (e.g. 2^31+1 can't be
    // encoded that way). However, we can convert uint to double without losing precision.
    // QVariant.toDouble() conveniently takes care of the conversion for us.
    case QVariant::UInt:
    case QVariant::Double:
        error = pps_encoder_add_double(encoder, name, data.toDouble());
        errorFunction = "pps_encoder_add_double";
        break;
    case QVariant::Int:
        error = pps_encoder_add_int(encoder, name, data.toInt());
        errorFunction = "pps_encoder_add_int";
        break;
    case QVariant::LongLong:
        error = pps_encoder_add_int64(encoder, name, data.toLongLong());
        errorFunction = "pps_encoder_add_int64";
        break;
    case QVariant::String:
        error = pps_encoder_add_string(encoder, name, data.toString().toUtf8().constData());
        errorFunction = "pps_encoder_add_string";
        break;
    case QVariant::List:
        error = pps_encoder_start_array(encoder, name);
        errorFunction = "pps_encoder_start_array";
        if (error == PPS_ENCODER_OK) {
            encodeArray(encoder, data.toList(), ok);
            error = pps_encoder_end_array(encoder);
            errorFunction = "pps_encoder_end_array";
        }
        break;
    case QVariant::Map:
        error = pps_encoder_start_object(encoder, name);
        errorFunction = "pps_encoder_start_object";
        if (error == PPS_ENCODER_OK) {
            encodeObject(encoder, data.toMap(), ok);
            error = pps_encoder_end_object(encoder);
            errorFunction = "pps_encoder_end_object";
        }
        break;
    case QVariant::Invalid:
        error = pps_encoder_add_null(encoder, name);
        errorFunction = "pps_encoder_add_null";
        break;
    default:
        qWarning("QPpsObjectPrivate::encodeData: the type of the parameter data is invalid");
        *ok = false;
        return;
    }

    if (error != PPS_ENCODER_OK) {
        qWarning("QPpsObjectPrivate::encodeData: %s failed", errorFunction);
        *ok = false;
    } else {
        *ok = true;
    }
}

void QPpsObjectPrivate::encodeArray(pps_encoder_t *encoder, const QVariantList &data, bool *ok)
{
    for (QVariantList::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) {
        encodeData(encoder, 0, *it, ok);
        if (!(*ok))
            return;
    }
    // if the passed data is empty, nothing went wrong and ok is set to true
    *ok = true;
}

void QPpsObjectPrivate::encodeObject(pps_encoder_t *encoder, const QVariantMap &data, bool *ok)
{
    for (QVariantMap::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) {
        encodeData(encoder, it.key().toUtf8().constData(), it.value(), ok);
        if (!(*ok))
            return;
    }
    // if the passed data is empty, nothing went wrong and ok is set to true
    *ok = true;
}



///////////////////////////////////////////////////////////////////////////////
//
// QPpsObjectPrivate
//
///////////////////////////////////////////////////////////////////////////////

QPpsObject::QPpsObject(const QString &path, QObject *parent)
    : QObject(*new QPpsObjectPrivate(path), parent)
{
}

QPpsObject::~QPpsObject()
{
    // RAII - ensure file gets closed
    if (isOpen())
        close();
}

int QPpsObject::error() const
{
    Q_D(const QPpsObject);
    return d->error;
}

QString QPpsObject::errorString() const
{
    Q_D(const QPpsObject);
    return qt_error_string(d->error);
}

bool QPpsObject::isReadyReadEnabled() const
{
    Q_D(const QPpsObject);

    // query state of read ready signal
    return d->readyReadEnabled;
}

void QPpsObject::setReadyReadEnabled(bool enable)
{
    Q_D(QPpsObject);

    // toggle whether socket notifier will emit a signal on read ready
    d->readyReadEnabled = enable;
    if (isOpen())
        d->notifier->setEnabled(enable);
}

bool QPpsObject::isBlocking() const
{
    Q_D(const QPpsObject);

    // reset last error
    d->error = EOK;

    // abort if file not open
    if (!isOpen()) {
        d->error = EBADF;
        return false;
    }

    // query file status flags
    int flags = fcntl(d->fd, F_GETFL);
    if (flags == -1) {
        d->error = errno;
        return false;
    }
    // check if non-blocking flag is unset
    return ((flags & O_NONBLOCK) != O_NONBLOCK);
}

bool QPpsObject::setBlocking(bool enable)
{
    Q_D(QPpsObject);

    // reset last error
    d->error = EOK;

    // abort if file not open
    if (!isOpen()) {
        d->error = EBADF;
        return false;
    }

    // query file status flags
    int flags = fcntl(d->fd, F_GETFL);
    if (flags == -1) {
        d->error = errno;
        return false;
    }

    // configure non-blocking flag
    if (enable)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;

    // update file status flags
    flags = fcntl(d->fd, F_SETFL, flags);
    if (flags == -1) {
        d->error = errno;
        return false;
    }

    return true;
}

bool QPpsObject::isOpen() const
{
    Q_D(const QPpsObject);
    return (d->fd != -1);
}

bool QPpsObject::open(QPpsObject::OpenModes mode)
{
    Q_D(QPpsObject);

    // reset last error
    d->error = EOK;

    // abort if file already open
    if (isOpen()) {
        d->error = EBUSY;
        return false;
    }

    // convert pps flags to open flags
    int oflags = 0;
    if ((mode & QPpsObject::Publish) && (mode & QPpsObject::Subscribe))
        oflags |= O_RDWR;
    else if (mode & QPpsObject::Publish)
        oflags |= O_WRONLY;
    else if (mode & QPpsObject::Subscribe)
        oflags |= O_RDONLY;

    if (mode & QPpsObject::Create)
        oflags |= O_CREAT | O_EXCL;

    if (mode & QPpsObject::DeleteContents)
        oflags |= O_TRUNC;

    // open pps file
    d->fd = qt_safe_open(d->path.toUtf8().data(), oflags, 0666);
    if (d->fd == -1) {
        d->error = errno;
        return false;
    }
    // wire up socket notifier to know when reads are ready
    d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this);
    d->notifier->setEnabled(d->readyReadEnabled);
    QObject::connect(d->notifier, &QSocketNotifier::activated, this, &QPpsObject::readyRead);
    return true;
}

bool QPpsObject::close()
{
    Q_D(QPpsObject);

    // reset last error
    d->error = EOK;

    // abort if file not open
    if (!isOpen()) {
        d->error = EBADF;
        return false;
    }

    // shutdown socket notifier
    delete d->notifier;
    d->notifier = 0;

    // close pps file
    const int result = qt_safe_close(d->fd);
    d->fd = -1;

    // check success of operation
    if (result != 0) {
        d->error = errno;
        return false;
    }
    return true;
}

QByteArray QPpsObject::read(bool *ok)
{
    Q_D(QPpsObject);

    // reset last error
    d->error = EOK;

    // abort if file not open
    if (!isOpen()) {
        d->error = EBADF;
        safeAssign(ok, false);
        return QByteArray();
    }

    const int maxSize = ppsMaxSize->value;
    if (maxSize == -1) {
        qWarning("QPpsObject::read: maxSize is equal to -1");
        safeAssign(ok, false);
        return QByteArray();
    }

    QByteArray byteArray;
    byteArray.resize(maxSize); // resize doesn't initialize the data
    const int result = qt_safe_read(d->fd, byteArray.data(), byteArray.size());

    if (result == -1) {
        d->error = errno;
        qWarning() << "QPpsObject::read failed to read pps data, error " << errorString();
        safeAssign(ok, false);
        return QByteArray(); // Specifically return a default-constructed QByteArray.
    }
    if (result == 0) {
        // normalize the behavior of read() when no data is ready so a pps object
        // put in non-blocking mode via opening w/o wait (read returns 0) looks
        // the same as a pps object put in non-blocking mode by setting O_NONBLOCK
        // (read returns EAGAIN)
        d->error = EAGAIN;
        safeAssign(ok, false);
        return QByteArray(); // Specifically return a default-constructed QByteArray.
    }
    // resize byte array to amount actually read
    byteArray.resize(result);
    safeAssign(ok, true);
    return byteArray;
}

bool QPpsObject::write(const QByteArray &byteArray)
{
    Q_D(QPpsObject);

    // reset last error
    d->error = EOK;

    // abort if file not open
    if (!isOpen()) {
        d->error = EBADF;
        return false;
    }

    // write entire byte array to pps file
    const int result = qt_safe_write(d->fd, byteArray.data(), byteArray.size());
    if (result == -1)
        d->error = errno;

    return (result == byteArray.size());
}

int QPpsObject::writeMessage(const QString &msg, const QVariantMap &dat)
{
    // Treat empty msg as an encoding error
    if (msg.isEmpty())
        return -1;

    bool ok;
    QByteArray byteArray = encodeMessage(msg, dat, &ok);

    if (!ok)
        return -1;

    ok = write(byteArray);
    if (!ok)
        return error();

    return EOK;
}

int QPpsObject::writeMessage(const QString &msg, const QString &id, const QVariantMap &dat)
{
    // Treat empty msg or id as an encoding error
    if (msg.isEmpty() || id.isEmpty())
        return -1;

    bool ok;
    QByteArray byteArray = encodeMessage(msg, id, dat, &ok);

    if (!ok)
        return -1;

    ok = write(byteArray);
    if (!ok)
        return error();

    return EOK;
}

bool QPpsObject::remove()
{
    Q_D(QPpsObject);

    // reset last error
    d->error = EOK;

    // delete pps file
    const int result = unlink(d->path.toUtf8().data());

    // check success of operation
    if (result != 0) {
        d->error = errno;
        return false;
    }
    return true;
}

// static
QVariantMap QPpsObject::decode(const QByteArray &rawData, bool *ok)
{
    QPpsAttributeMap mapData = decodeWithFlags(rawData, 0, ok);

    // If *ok is false, then mapData is empty, so the resulting QVariantMap
    // will also be empty, as desired.
    return QPpsObjectPrivate::variantMapFromPpsAttributeMap(mapData);
}

// static
QPpsAttributeMap QPpsObject::decodeWithFlags(const QByteArray &rawData, bool *ok)
{
    return QPpsObject::decodeWithFlags(rawData, 0, ok);
}

// static
QPpsAttributeMap QPpsObject::decodeWithFlags(const QByteArray &rawData,
    QPpsAttribute *objectAttribute, bool *ok)
{
    safeAssign(ok, true);

    bool success = false;
    QPpsAttributeMap mapData =  QPpsObjectPrivate::decode(rawData, &success);
    if (!success) {
        safeAssign(ok, false);
        return QPpsAttributeMap();
    }

    // The object name is the key of the first element, and the flags of that attribute
    // give the status for the object as a whole.
    if (!mapData.isEmpty() && objectAttribute) {
        QString extractedName = mapData.begin().key();
        QPpsAttribute topmostAttribute = mapData.begin().value();
        QPpsAttribute::Flags topmostFlags = topmostAttribute.flags();
        QPpsAttribute toplevelAttribute =
            QPpsAttributePrivate::createPpsAttribute(extractedName, topmostFlags);
        *objectAttribute = toplevelAttribute;
    }

    return mapData;
}


// static
QByteArray QPpsObject::encode(const QVariantMap &ppsData, bool *ok)
{
    safeAssign(ok, true);

    bool success = false;
    QByteArray byteArray = QPpsObjectPrivate::encode(ppsData, &success);
    if (!success) {
        safeAssign(ok, false);
        return QByteArray();
    }
    return byteArray;
}

// static
QByteArray QPpsObject::encodeMessage(const QString &msg, const QVariantMap &dat, bool *ok)
{
    safeAssign(ok, true);

    // Treat empty msg as an encoding error
    if (msg.isEmpty()) {
        safeAssign(ok, false);
        return QByteArray();
    }

    QVariantMap ppsData;
    ppsData[QStringLiteral("msg")] = msg;
    ppsData[QStringLiteral("dat")] = dat;

    return QPpsObject::encode(ppsData, ok);
}

// static
QByteArray QPpsObject::encodeMessage(const QString &msg, const QString &id, const QVariantMap &dat,
                                     bool *ok)
{
    safeAssign(ok, true);

    // Treat empty msg or id as an encoding error
    if (msg.isEmpty() || id.isEmpty()) {
        safeAssign(ok, false);
        return QByteArray();
    }

    QVariantMap ppsData;
    ppsData[QStringLiteral("msg")] = msg;
    ppsData[QStringLiteral("id")] = id;
    ppsData[QStringLiteral("dat")] = dat;

    return QPpsObject::encode(ppsData, ok);
}

// static
int QPpsObject::sendMessage(const QString &path, const QString &message)
{
    QPpsObject pps(path);

    bool ok = pps.open(QPpsObject::Publish);
    if (!ok)
        return pps.error();

    ok = pps.write(message.toLocal8Bit());
    if (!ok)
        return pps.error();

    return EOK;
}

// static
int QPpsObject::sendMessage(const QString &path, const QVariantMap &message)
{
    QPpsObject pps(path);

    bool ok = pps.open(QPpsObject::Publish);
    if (!ok)
        return pps.error();

    QByteArray payload = QPpsObject::encode(message, &ok);
    if (!ok)
        return -1;

    ok = pps.write(payload);
    if (!ok)
        return pps.error();

    return EOK;
}

// static
int QPpsObject::sendMessage(const QString &path, const QString &msg, const QVariantMap &dat)
{
    // Treat empty msg as an encoding error
    if (msg.isEmpty())
        return -1;

    QPpsObject pps(path);

    bool ok = pps.open(QPpsObject::Publish);
    if (!ok)
        return pps.error();

    QByteArray payload = QPpsObject::encodeMessage(msg, dat, &ok);
    if (!ok)
        return -1;

    ok = pps.write(payload);
    if (!ok)
        return pps.error();

    return EOK;
}

// static
int QPpsObject::sendMessage(const QString &path, const QByteArray &ppsData)
{
    QPpsObject pps(path);

    bool ok = pps.open(QPpsObject::Publish);
    if (!ok)
        return pps.error();

    ok = pps.write(ppsData);
    if (!ok)
        return pps.error();

    return EOK;
}

QT_END_NAMESPACE
