/****************************************************************************
**
** Copyright (C) 2018 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 "qscxmlglobals_p.h"
#include "qscxmlexecutablecontent_p.h"
#include "qscxmlcompiler_p.h"
#include "qscxmlevent_p.h"

QT_BEGIN_NAMESPACE

using namespace QScxmlExecutableContent;

/*!
    \namespace QScxmlExecutableContent
    \inmodule QtScxml
    \since 5.8
    \brief The QScxmlExecutableContent namespace contains various types used
    to interpret executable content in state machines.
 */

/*!
    \typedef QScxmlExecutableContent::ContainerId
    \inmodule QtScxml
    \since 5.8
    \brief ID for a container holding executable content.
 */

/*!
    \typedef QScxmlExecutableContent::EvaluatorId
    \inmodule QtScxml
    \since 5.8
    \brief ID for a unit of executable content.
 */

/*!
    \typedef QScxmlExecutableContent::InstructionId
    \inmodule QtScxml
    \since 5.8
    \brief ID for an instruction of executable content.
 */

/*!
    \typedef QScxmlExecutableContent::StringId
    \inmodule QtScxml
    \since 5.8
    \brief ID for a string contained in executable content.
 */

/*!
    \enum QScxmlExecutableContent::anonymous
    \since 5.8

    This enum type holds the invalid values for type definitions.

    \value NoContainer
           \l ContainerId is unknown.
    \value NoEvaluator
           \l EvaluatorId is unknown.
    \value NoInstruction
           \l InstructionId is unknown.
    \value NoString
           \l StringId is unknown.
*/

/*!
    \class QScxmlExecutableContent::EvaluatorInfo
    \brief The EvaluatorInfo class represents a unit of executable content.
    \since 5.8
    \inmodule QtScxml
 */

/*!
    \variable QScxmlExecutableContent::EvaluatorInfo::expr
    \brief The expression to be evaluated
 */

/*!
    \variable QScxmlExecutableContent::EvaluatorInfo::context
    \brief The context for evaluating the expression
 */

/*!
    \class QScxmlExecutableContent::AssignmentInfo
    \brief The AssingmentInfo class represents a data assignment.
    \since 5.8
    \inmodule QtScxml
 */

/*!
    \variable QScxmlExecutableContent::AssignmentInfo::expr
    \brief The expression to be evaluated
 */

/*!
    \variable QScxmlExecutableContent::AssignmentInfo::context
    \brief The context for evaluating the expression
 */

/*!
    \variable QScxmlExecutableContent::AssignmentInfo::dest
    \brief The name of the data item to assign to
 */

/*!
    \class QScxmlExecutableContent::ForeachInfo
    \brief The ForeachInfo class represents a foreach construct.
    \since 5.8
    \inmodule QtScxml
 */

/*!
    \variable QScxmlExecutableContent::ForeachInfo::array
    \brief The name of the array that is iterated over
 */

/*!
    \variable QScxmlExecutableContent::ForeachInfo::item
    \brief The name of the iteration variable
 */

/*!
    \variable QScxmlExecutableContent::ForeachInfo::index
    \brief The name of the index variable
 */

/*!
    \variable QScxmlExecutableContent::ForeachInfo::context
    \brief The context for evaluating the expression
 */

/*!
    \class QScxmlExecutableContent::ParameterInfo
    \brief The ParameterInfo class represents a parameter to a service
    invocation.
    \since 5.8
    \inmodule QtScxml
 */

/*!
    \variable QScxmlExecutableContent::ParameterInfo::name
    \brief The name of the parameter
 */

/*!
    \variable QScxmlExecutableContent::ParameterInfo::expr
    \brief The expression to be evaluated
 */

/*!
    \variable QScxmlExecutableContent::ParameterInfo::location
    \brief The data model name of the item to be passed as a parameter
 */

/*!
    \class QScxmlExecutableContent::InvokeInfo
    \brief The InvokeInfo class represents a service invocation.
    \since 5.8
    \inmodule QtScxml
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::id
    \brief The ID specified by the \c id attribute in the \c <invoke> element.
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::prefix
    \brief The unique prefix for this invocation in the context of the state
    from which it is called
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::location
    \brief The data model location to write the invocation ID to
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::context
    \brief The context to interpret the location in
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::expr
    \brief The expression representing the srcexpr of the invoke element
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::finalize
    \brief The ID of the container of executable content to be run on finalizing
    the invocation
 */

/*!
    \variable QScxmlExecutableContent::InvokeInfo::autoforward
    \brief Whether events should automatically be forwarded to the invoked
    service
 */


#ifndef BUILD_QSCXMLC
static int parseTime(const QString &t, bool *ok = nullptr)
{
    if (t.isEmpty()) {
        if (ok)
            *ok = false;
        return -1;
    }
    bool negative = false;
    int startPos = 0;
    if (t[0] == QLatin1Char('-')) {
        negative = true;
        ++startPos;
    } else if (t[0] == QLatin1Char('+')) {
        ++startPos;
    }
    int pos = startPos;
    for (int endPos = t.length(); pos < endPos; ++pos) {
        auto c = t[pos];
        if (c < QLatin1Char('0') || c > QLatin1Char('9'))
            break;
    }
    if (pos == startPos) {
        if (ok) *ok = false;
        return -1;
    }
    int value = t.midRef(startPos, pos - startPos).toInt(ok);
    if (ok && !*ok) return -1;
    if (t.length() == pos + 1 && t[pos] == QLatin1Char('s')) {
        value *= 1000;
    } else if (t.length() != pos + 2 || t[pos] != QLatin1Char('m') || t[pos + 1] != QLatin1Char('s')) {
        if (ok) *ok = false;
        return -1;
    }
    return negative ? -value : value;
}

QScxmlExecutionEngine::QScxmlExecutionEngine(QScxmlStateMachine *stateMachine)
    : stateMachine(stateMachine)
{
    Q_ASSERT(stateMachine);
}

bool QScxmlExecutionEngine::execute(ContainerId id, const QVariant &extraData)
{
    Q_ASSERT(stateMachine);

    if (id == NoInstruction)
        return true;

    const InstructionId *ip = stateMachine->tableData()->instructions() + id;
    this->extraData = extraData;
    bool result = true;
    step(ip, &result);
    this->extraData = QVariant();
    return result;
}

const InstructionId *QScxmlExecutionEngine::step(const InstructionId *ip, bool *ok)
{
    auto dataModel = stateMachine->dataModel();
    auto tableData = stateMachine->tableData();

    *ok = true;
    auto instr = reinterpret_cast<const Instruction *>(ip);
    switch (instr->instructionType) {
    case Instruction::Sequence: {
        qCDebug(qscxmlLog) << stateMachine << "Executing sequence step";
        const InstructionSequence *sequence = reinterpret_cast<const InstructionSequence *>(instr);
        ip = sequence->instructions();
        const InstructionId *end = ip + sequence->entryCount;
        while (ip < end) {
            ip = step(ip, ok);
            if (!(*ok)) {
                qCDebug(qscxmlLog) << stateMachine << "Finished sequence step UNsuccessfully";
                return end;
            }
        }
        qCDebug(qscxmlLog) << stateMachine << "Finished sequence step successfully";
        return ip;
    }

    case Instruction::Sequences: {
        qCDebug(qscxmlLog) << stateMachine << "Executing sequences step";
        const InstructionSequences *sequences
                = reinterpret_cast<const InstructionSequences *>(instr);
        ip += sequences->size();
        for (int i = 0; i != sequences->sequenceCount; ++i) {
            bool ignored;
            const InstructionId *sequence = sequences->at(i);
            step(sequence, &ignored);
        }
        qCDebug(qscxmlLog) << stateMachine << "Finished sequences step";
        return ip;
    }

    case Instruction::Send: {
        qCDebug(qscxmlLog) << stateMachine << "Executing send step";
        const Send *send = reinterpret_cast<const Send *>(instr);
        ip += send->size();

        QString delay = tableData->string(send->delay);
        if (send->delayexpr != NoEvaluator) {
            delay = stateMachine->dataModel()->evaluateToString(send->delayexpr, ok);
            if (!(*ok))
                return ip;
        }

        QScxmlEvent *event = QScxmlEventBuilder(stateMachine, *send).buildEvent();
        if (!event) {
            *ok = false;
            return ip;
        }

        if (!delay.isEmpty()) {
            int msecs = parseTime(delay);
            if (msecs >= 0) {
                event->setDelay(msecs);
            } else {
                qCDebug(qscxmlLog) << stateMachine << "failed to parse delay time" << delay;
                *ok = false;
                return ip;
            }
        }

        stateMachine->submitEvent(event);
        return ip;
    }

    case Instruction::JavaScript: {
        qCDebug(qscxmlLog) << stateMachine << "Executing script step";
        const JavaScript *javascript = reinterpret_cast<const JavaScript *>(instr);
        ip += javascript->size();
        dataModel->evaluateToVoid(javascript->go, ok);
        return ip;
    }

    case Instruction::If: {
        qCDebug(qscxmlLog) << stateMachine << "Executing if step";
        const If *_if = reinterpret_cast<const If *>(instr);
        ip += _if->size();
        auto blocks = _if->blocks();
        for (qint32 i = 0; i < _if->conditions.count; ++i) {
            bool conditionOk = true;
            if (dataModel->evaluateToBool(_if->conditions.at(i), &conditionOk) && conditionOk) {
                const InstructionId *block = blocks->at(i);
                step(block, ok);
                qCDebug(qscxmlLog) << stateMachine << "Finished if step";
                return ip;
            }
        }

        if (_if->conditions.count < blocks->sequenceCount)
            step(blocks->at(_if->conditions.count), ok);

        return ip;
    }

    case Instruction::Foreach: {
        class LoopBody: public QScxmlDataModel::ForeachLoopBody // If only we could put std::function in public API, we could use a lambda here. Alas....
        {
            QScxmlExecutionEngine *engine;
            const InstructionId *loopStart;

        public:
            LoopBody(QScxmlExecutionEngine *engine, const InstructionId *loopStart)
                : engine(engine)
                , loopStart(loopStart)
            {}

            void run(bool *ok) override
            {
                engine->step(loopStart, ok);
            }
        };

        qCDebug(qscxmlLog) << stateMachine << "Executing foreach step";
        const Foreach *_foreach = reinterpret_cast<const Foreach *>(instr);
        const InstructionId *loopStart = _foreach->blockstart();
        ip += _foreach->size();
        LoopBody body(this, loopStart);
        dataModel->evaluateForeach(_foreach->doIt, ok, &body);
        return ip;
    }

    case Instruction::Raise: {
        qCDebug(qscxmlLog) << stateMachine << "Executing raise step";
        const Raise *raise = reinterpret_cast<const Raise *>(instr);
        ip += raise->size();
        auto name = tableData->string(raise->event);
        auto event = new QScxmlEvent;
        event->setName(name);
        event->setEventType(QScxmlEvent::InternalEvent);
        stateMachine->submitEvent(event);
        return ip;
    }

    case Instruction::Log: {
        qCDebug(qscxmlLog) << stateMachine << "Executing log step";
        const Log *log = reinterpret_cast<const Log *>(instr);
        ip += log->size();
        QString str;
        if (log->expr != NoEvaluator) {
            str = dataModel->evaluateToString(log->expr, ok);
            if (!*ok)
                qCWarning(qscxmlLog) << stateMachine << "Could not evaluate <log> expr to string.";
        }

        const QString label = tableData->string(log->label);
        qCDebug(scxmlLog) << label << ":" << str;
        QMetaObject::invokeMethod(stateMachine,
                                  "log",
                                  Qt::QueuedConnection,
                                  Q_ARG(QString, label),
                                  Q_ARG(QString, str));
        return ip;
    }

    case Instruction::Cancel: {
        qCDebug(qscxmlLog) << stateMachine << "Executing cancel step";
        const Cancel *cancel = reinterpret_cast<const Cancel *>(instr);
        ip += cancel->size();
        QString e = tableData->string(cancel->sendid);
        if (cancel->sendidexpr != NoEvaluator)
            e = dataModel->evaluateToString(cancel->sendidexpr, ok);
        if (*ok && !e.isEmpty())
            stateMachine->cancelDelayedEvent(e);
        return ip;
    }

    case Instruction::Assign: {
        qCDebug(qscxmlLog) << stateMachine << "Executing assign step";
        const Assign *assign = reinterpret_cast<const Assign *>(instr);
        ip += assign->size();
        dataModel->evaluateAssignment(assign->expression, ok);
        return ip;
    }

    case Instruction::Initialize: {
        qCDebug(qscxmlLog) << stateMachine << "Executing initialize step";
        const Initialize *init = reinterpret_cast<const Initialize *>(instr);
        ip += init->size();
        dataModel->evaluateInitialization(init->expression, ok);
        return ip;
    }

    case Instruction::DoneData: {
        qCDebug(qscxmlLog) << stateMachine << "Executing DoneData step";
        const DoneData *doneData = reinterpret_cast<const DoneData *>(instr);

        QString eventName = QStringLiteral("done.state.") + extraData.toString();
        QScxmlEventBuilder event(stateMachine, eventName, doneData);
        auto e = event();
        e->setEventType(QScxmlEvent::InternalEvent);
        qCDebug(qscxmlLog) << stateMachine << "submitting event" << eventName;
        stateMachine->submitEvent(e);
        return ip;
    }

    default:
        Q_UNREACHABLE();
        *ok = false;
        return ip;
    }
}
#endif // BUILD_QSCXMLC

QT_END_NAMESPACE
