/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtScxml 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 "qscxmlexecutablecontent_p.h"
#include "qscxmlevent_p.h"
#include "qscxmlstatemachine_p.h"

#include <qjsondocument.h>
#include <qjsonobject.h>

QT_BEGIN_NAMESPACE

using namespace QScxmlExecutableContent;

QAtomicInt QScxmlEventBuilder::idCounter = QAtomicInt(0);

QScxmlEvent *QScxmlEventBuilder::buildEvent()
{
    auto dataModel = stateMachine ? stateMachine->dataModel() : nullptr;
    auto tableData = stateMachine ? stateMachine->tableData() : nullptr;

    QString eventName = event;
    bool ok = true;
    if (eventexpr != NoEvaluator) {
        eventName = dataModel->evaluateToString(eventexpr, &ok);
        ok = true; // ignore failure.
    }

    QVariant data;
    if ((!params || params->count == 0) && (!namelist || namelist->count == 0)) {
        if (contentExpr == NoEvaluator) {
            data = contents;
        } else {
            data = dataModel->evaluateToVariant(contentExpr, &ok);
        }
        if (!ok) {
            // expr evaluation failure results in the data property of the event being set to null. See e.g. test528.
            data = QVariant(QMetaType::VoidStar, 0);
        }
    } else {
        QVariantMap keyValues;
        if (evaluate(params, stateMachine, keyValues)) {
            if (namelist) {
                for (qint32 i = 0; i < namelist->count; ++i) {
                    QString name = tableData->string(namelist->const_data()[i]);
                    keyValues.insert(name, dataModel->scxmlProperty(name));
                }
            }
            data = keyValues;
        } else {
            // If the evaluation of the <param> tags fails, set _event.data to an empty string.
            // See test343.
            data = QVariant(QMetaType::VoidStar, 0);
        }
    }

    QString sendid = id;
    if (!idLocation.isEmpty()) {
        sendid = generateId();
        ok = stateMachine->dataModel()->setScxmlProperty(idLocation, sendid, tableData->string(instructionLocation));
        if (!ok)
            return nullptr;
    }

    QString origin = target;
    if (targetexpr != NoEvaluator) {
        origin = dataModel->evaluateToString(targetexpr, &ok);
        if (!ok)
            return nullptr;
    }
    if (origin.isEmpty()) {
        if (eventType == QScxmlEvent::ExternalEvent) {
            origin = QStringLiteral("#_internal");
        }
    } else if (origin == QStringLiteral("#_parent")) {
        // allow sending messages to the parent, independently of whether we're invoked or not.
    } else if (!origin.startsWith(QLatin1Char('#'))) {
        // [6.2.4] and test194.
        submitError(QStringLiteral("error.execution"),
                    QStringLiteral("Error in %1: %2 is not a legal target")
                    .arg(tableData->string(instructionLocation), origin),
                    sendid);
        return nullptr;
    } else if (!stateMachine->isDispatchableTarget(origin)) {
        // [6.2.4] and test521.
        submitError(QStringLiteral("error.communication"),
                    QStringLiteral("Error in %1: cannot dispatch to target '%2'")
                    .arg(tableData->string(instructionLocation), origin),
                    sendid);
        return nullptr;
    }

    QString origintype = type;
    if (origintype.isEmpty()) {
        // [6.2.5] and test198
        origintype = QStringLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor");
    }
    if (typeexpr != NoEvaluator) {
        origintype = dataModel->evaluateToString(typeexpr, &ok);
        if (!ok)
            return nullptr;
    }
    if (!origintype.isEmpty()
            && origintype != QStringLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor")) {
        // [6.2.5] and test199
        submitError(QStringLiteral("error.execution"),
                    QStringLiteral("Error in %1: %2 is not a valid type")
                    .arg(tableData->string(instructionLocation), origintype),
                    sendid);
        return nullptr;
    }

    QString invokeid;
    if (stateMachine && stateMachine->isInvoked()) {
        invokeid = stateMachine->sessionId();
    }

    QScxmlEvent *event = new QScxmlEvent;
    event->setName(eventName);
    event->setEventType(eventType);
    event->setData(data);
    event->setSendId(sendid);
    event->setOrigin(origin);
    event->setOriginType(origintype);
    event->setInvokeId(invokeid);
    return event;
}

QScxmlEvent *QScxmlEventBuilder::errorEvent(QScxmlStateMachine *stateMachine, const QString &name,
                                            const QString &message, const QString &sendid)
{
    QScxmlEventBuilder event;
    event.stateMachine = stateMachine;
    event.event = name;
    event.eventType = QScxmlEvent::PlatformEvent; // Errors are platform events. See e.g. test331.
    // _event.data == null, see test528
    event.id = sendid;
    auto error = event();
    error->setErrorMessage(message);
    return error;
}

bool QScxmlEventBuilder::evaluate(const ParameterInfo &param, QScxmlStateMachine *stateMachine,
                                  QVariantMap &keyValues)
{
    auto dataModel = stateMachine->dataModel();
    auto tableData = stateMachine->tableData();
    if (param.expr != NoEvaluator) {
        bool success = false;
        auto v = dataModel->evaluateToVariant(param.expr, &success);
        keyValues.insert(tableData->string(param.name), v);
        return success;
    }

    QString loc;
    if (param.location != QScxmlExecutableContent::NoString) {
        loc = tableData->string(param.location);
    }

    if (loc.isEmpty()) {
        return false;
    }

    if (dataModel->hasScxmlProperty(loc)) {
        keyValues.insert(tableData->string(param.name), dataModel->scxmlProperty(loc));
        return true;
    } else {
        submitError(QStringLiteral("error.execution"),
                    QStringLiteral("Error in <param>: %1 is not a valid location")
                    .arg(loc));
        return false;
    }
}

bool QScxmlEventBuilder::evaluate(const QScxmlExecutableContent::Array<ParameterInfo> *params,
                                  QScxmlStateMachine *stateMachine, QVariantMap &keyValues)
{
    if (!params)
        return true;

    auto paramPtr = params->const_data();
    for (qint32 i = 0; i != params->count; ++i, ++paramPtr) {
        if (!evaluate(*paramPtr, stateMachine, keyValues))
            return false;
    }

    return true;
}

void QScxmlEventBuilder::submitError(const QString &type, const QString &msg, const QString &sendid)
{
    QScxmlStateMachinePrivate::get(stateMachine)->submitError(type, msg, sendid);
}

/*!
 * \class QScxmlEvent
 * \brief The QScxmlEvent class is an event for a Qt SCXML state machine.
 * \since 5.7
 * \inmodule QtScxml
 *
 * SCXML \e events drive transitions. Most events are generated by using the
 * \c <raise> and \c <send> elements in the application. The state machine
 * automatically generates some mandatory events, such as errors.
 *
 * For more information, see
 * \l {SCXML Specification - 5.10.1 The Internal Structure of Events}.
 * For more information about how the Qt SCXML API differs from the
 * specification, see \l {SCXML Compliance}.
 *
 * \sa QScxmlStateMachine
 */

/*!
    \enum QScxmlEvent::EventType

    This enum type specifies the type of an SCXML event:

    \value  PlatformEvent
            An event generated internally by the state machine. For example,
            errors.
    \value  InternalEvent
            An event generated by a \c <raise> element.
    \value  ExternalEvent
            An event generated by a \c <send> element.
 */

/*!
 * Creates a new external SCXML event.
 */
QScxmlEvent::QScxmlEvent()
    : d(new QScxmlEventPrivate)
{ }

/*!
 * Destroys the SCXML event.
 */
QScxmlEvent::~QScxmlEvent()
{
    delete d;
}

/*!
    \property QScxmlEvent::scxmlType
    \brief The event type.

*/

/*!
 * Returns the event type.
 */
QString QScxmlEvent::scxmlType() const
{
    switch (d->eventType) {
    case PlatformEvent:
        return QLatin1String("platform");
    case InternalEvent:
        return QLatin1String("internal");
    case ExternalEvent:
        break;
    }
    return QLatin1String("external");
}

/*!
 * Clears the contents of the event.
 */
void QScxmlEvent::clear()
{
    *d = QScxmlEventPrivate();
}

/*!
 * Assigns \a other to this SCXML event and returns a reference to this SCXML
 * event.
 */
QScxmlEvent &QScxmlEvent::operator=(const QScxmlEvent &other)
{
    *d = *other.d;
    return *this;
}

/*!
 * Constructs a copy of \a other.
 */
QScxmlEvent::QScxmlEvent(const QScxmlEvent &other)
    : d(new QScxmlEventPrivate(*other.d))
{
}

/*!
    \property QScxmlEvent::name

    \brief the name of the event.

    If the event is generated inside the SCXML document, this property holds the
    value of the \e event attribute specified inside the \c <raise> or \c <send>
    element.

    If the event is created in the C++ code and submitted to the
    QScxmlStateMachine, the value of this property is matched against the value
    of the \e event attribute specified inside the \c <transition> element in
    the SCXML document.
*/

/*!
 * Returns the name of the event.
 */
QString QScxmlEvent::name() const
{
    return d->name;
}

/*!
 * Sets the name of the event to \a name.
 */
void QScxmlEvent::setName(const QString &name)
{
    d->name = name;
}

/*!
    \property QScxmlEvent::sendId

    \brief the ID of the event.

    The ID is used by the \c <cancel> element to identify the event to be
    canceled.

    \note The state machine generates a unique ID if the \e id attribute is not
    specified in the \c <send> element. The generated ID can be accessed through
    this property.
*/

/*!
 * Returns the ID of the event.
 */
QString QScxmlEvent::sendId() const
{
    return d->sendid;
}

/*!
 * Sets the ID \a sendid for this event.
 */
void QScxmlEvent::setSendId(const QString &sendid)
{
    d->sendid = sendid;
}

/*!
    \property QScxmlEvent::origin

    \brief the URI that points to the origin of an SCXML event.

    The origin is equivalent to the \e target attribute of the \c <send>
    element.
*/

/*!
 * Returns a URI that points to the origin of an SCXML event.
 */
QString QScxmlEvent::origin() const
{
    return d->origin;
}

/*!
 * Sets the origin of an SCXML event to \a origin.
 *
 * \sa QScxmlEvent::origin
 */
void QScxmlEvent::setOrigin(const QString &origin)
{
    d->origin = origin;
}

/*!
    \property QScxmlEvent::originType

    \brief the origin type of an SCXML event.

    The origin type is equivalent to the \e type attribute of the \c <send>
    element.
*/

/*!
 * Returns the origin type of an SCXML event.
 */
QString QScxmlEvent::originType() const
{
    return d->originType;
}

/*!
 * Sets the origin type of an SCXML event to \a origintype.
 *
 * \sa QScxmlEvent::originType
 */
void QScxmlEvent::setOriginType(const QString &origintype)
{
    d->originType = origintype;
}

/*!
    \property QScxmlEvent::invokeId

    \brief the ID of the invoked state machine if the event is generated by one.
*/

/*!
 * If this event is generated by an invoked state machine, returns the ID of
 * the \c <invoke> element. Otherwise, returns an empty value.
 */
QString QScxmlEvent::invokeId() const
{
    return d->invokeId;
}

/*!
 * Sets the ID of an invoked state machine to \a invokeid.
 * \sa QScxmlEvent::invokeId
 */
void QScxmlEvent::setInvokeId(const QString &invokeid)
{
    d->invokeId = invokeid;
}

/*!
    \property QScxmlEvent::delay

    \brief The delay in milliseconds after which the event is to be delivered
    after processing the \c <send> element.
*/

/*!
 * Returns the delay in milliseconds after which this event is to be delivered
 * after processing the \c <send> element.
 */
int QScxmlEvent::delay() const
{
    return d->delayInMiliSecs;
}

/*!
 * Sets the delay in milliseconds as the value of \a delayInMiliSecs.
 * \sa QScxmlEvent::delay
 */
void QScxmlEvent::setDelay(int delayInMiliSecs)
{
    d->delayInMiliSecs = delayInMiliSecs;
}
/*!
    \property QScxmlEvent::eventType

    \brief the type of the event.
*/

/*!
 * Returns the type of this event.
 * \sa QScxmlEvent::EventType
 */
QScxmlEvent::EventType QScxmlEvent::eventType() const
{
    return d->eventType;
}

/*!
 * Sets the event type to \a type.
 * \sa QScxmlEvent::eventType QScxmlEvent::EventType
 */
void QScxmlEvent::setEventType(const EventType &type)
{
    d->eventType = type;
}

/*!
    \property QScxmlEvent::data

    \brief the data included by the sender.

    When \c <param> elements are used in the \c <send> element, the data will
    contain a QVariantMap where the key is the \e name attribute, and the value
    is taken from the \e expr attribute or the \e location attribute.

    When a \c <content> element is used, the data will contain a single item
    with either the value of the \e expr attribute of the \c <content> element
    or the child data of the \c <content> element.
*/

/*!
 * Returns the data included by the sender.
 */
QVariant QScxmlEvent::data() const
{
    if (isErrorEvent())
        return QVariant();
    return d->data;
}

/*!
 * Sets the payload data to \a data.
 * \sa QScxmlEvent::data
 */
void QScxmlEvent::setData(const QVariant &data)
{
    if (!isErrorEvent())
        d->data = data;
}

/*!
    \property QScxmlEvent::errorEvent
    \brief Whether the event represents an error.
*/

/*!
 * Returns \c true when this is an error event, \c false otherwise.
 */
bool QScxmlEvent::isErrorEvent() const
{
    return eventType() == PlatformEvent && name().startsWith(QStringLiteral("error."));
}

/*!
    \property QScxmlEvent::errorMessage
    \brief An error message for an error event, or an empty QString.
*/

/*!
 * If this is an error event, returns the error message. Otherwise, returns an
 *         empty QString.
 */
QString QScxmlEvent::errorMessage() const
{
    if (!isErrorEvent())
        return QString();
    return d->data.toString();
}

/*!
 * If this is an error event, the \a message is set as the error message.
 */
void QScxmlEvent::setErrorMessage(const QString &message)
{
    if (isErrorEvent())
        d->data = message;
}

QByteArray QScxmlEventPrivate::debugString(QScxmlEvent *event)
{
    if (event == nullptr) {
        return "<null>";
    }

    QJsonObject o;
    if (!event->name().isNull())
        o[QStringLiteral("name")] = event->name();
    if (!event->scxmlType().isNull())
        o[QStringLiteral("type")] = event->scxmlType();
    if (!event->sendId().isNull())
        o[QStringLiteral("sendid")] = event->sendId();
    if (!event->origin().isNull())
        o[QStringLiteral("origin")] = event->origin();
    if (!event->originType().isNull())
        o[QStringLiteral("origintype")] = event->originType();
    if (!event->invokeId().isNull())
        o[QStringLiteral("invokeid")] = event->invokeId();
    if (!event->data().isNull())
        o[QStringLiteral("data")] = QJsonValue::fromVariant(event->data());

    return QJsonDocument(o).toJson(QJsonDocument::Compact);
}

QT_END_NAMESPACE
