/****************************************************************************
**
** 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:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest>
#include <QObject>
#include <QXmlStreamReader>
#include <QtScxml/qscxmlcompiler.h>
#include <QtScxml/qscxmlstatemachine.h>
#include <QtScxml/qscxmlinvokableservice.h>
#include "ids1.h"
#include "statemachineunicodename.h"
#include "datainnulldatamodel.h"
#include "submachineunicodename.h"
#include "eventnames1.h"
#include "connection.h"
#include "topmachine.h"

enum { SpyWaitTime = 8000 };

class tst_Compiled: public QObject
{
    Q_OBJECT

private Q_SLOTS:
    void stateNames();
    void nullDataInit();
    void subMachineUnicodeName();
    void unicodeEventName();
    void connection();
    void myConnection();
    void topMachine();
    void topMachineDynamic();
    void publicSignals();
};

void tst_Compiled::stateNames()
{
    ids1 stateMachine;

    // The states have to be appear in document order:
    QStringList ids1States({
        "foo.bar",
        "foo-bar",
        "foo_bar",
        "_",
        "näl",
        "n_0xe4_l",
        "_VALID",
        "__valid",
        "qÿ̀i",
    });

    QCOMPARE(stateMachine.stateNames(false), ids1States);

    for (const QString &state : qAsConst(ids1States)) {
        QVariant prop = stateMachine.property(state.toUtf8().constData());
        QVERIFY(!prop.isNull());
        QVERIFY(prop.isValid());
        QCOMPARE(prop.toBool(), false);
    }

    QVariant invalidProp = stateMachine.property("blabla");
    QVERIFY(invalidProp.isNull());
    QVERIFY(!invalidProp.isValid());

    QStringList calculatorStates(QLatin1String("wrapper"));

    Calculator_0xe4_tateMachine stateMachine3;
    QCOMPARE(stateMachine3.stateNames(false), calculatorStates);
}

void tst_Compiled::nullDataInit()
{
    DataInNullDataModel nullData;
    QVERIFY(!nullData.init()); // raises an error, but doesn't crash
}

void tst_Compiled::subMachineUnicodeName()
{
    Directions1 directions;
    QSignalSpy stableStateSpy(&directions, SIGNAL(reachedStableState()));
    directions.start();
    stableStateSpy.wait(5000);
    QScxmlInvokableService *service = directions.invokedServices().value(0);
    QVERIFY(service);
    QCOMPARE(service->name(), QString("änywhere"));
}

void tst_Compiled::unicodeEventName()
{
    eventnames1 names;
    QSignalSpy stableStateSpy(&names, SIGNAL(reachedStableState()));
    names.start();

    stableStateSpy.wait(5000);

    QCOMPARE(names.activeStateNames(), QStringList(QLatin1String("a")));
    names.submitEvent("näl");
    stableStateSpy.wait(5000);
    QCOMPARE(names.activeStateNames(), QStringList(QLatin1String("b")));
}

class Receiver : public QObject
{
    Q_OBJECT
public slots:
    void receive(bool enabled)
    {
        received = received || enabled;
    }

    void enter()
    {
        entered = true;
    }

    void exit()
    {
        exited = true;
    }

public:
    bool received = false;
    bool entered = false;
    bool exited = false;
};

void tst_Compiled::connection()
{
    Connection stateMachine;

    Receiver receiverA;
    Receiver receiverA1;
    Receiver receiverA2;
    Receiver receiverB;
    Receiver receiverFinal;

    QMetaObject::Connection conA     = stateMachine.connectToState("a",     &receiverA,     SLOT(receive(bool)));
    QMetaObject::Connection conA1    = stateMachine.connectToState("a1",    &receiverA1,    SLOT(receive(bool)));
    QMetaObject::Connection conA2    = stateMachine.connectToState("a2",    &receiverA2,    SLOT(receive(bool)));
    QMetaObject::Connection conB     = stateMachine.connectToState("b",     &receiverB,     SLOT(receive(bool)));
    QMetaObject::Connection conFinal = stateMachine.connectToState("final", &receiverFinal, SLOT(receive(bool)));

    typedef QScxmlStateMachine QXSM;
    QMetaObject::Connection aEntry = stateMachine.connectToState("a", QXSM::onEntry(&receiverA, "enter"));
    QMetaObject::Connection aExit  = stateMachine.connectToState("a", QXSM::onExit(&receiverA, "exit"));

    QVERIFY(aEntry);
    QVERIFY(aExit);

    QVERIFY(conA);
    QVERIFY(conA1);
    QVERIFY(conA2);
    QVERIFY(conB);
    QVERIFY(conFinal);

    stateMachine.start();

    QTRY_VERIFY(receiverA.received);
    QTRY_VERIFY(receiverA1.received);
    QTRY_VERIFY(!receiverA2.received);
    QTRY_VERIFY(receiverB.received);
    QTRY_VERIFY(receiverFinal.received);

    QVERIFY(disconnect(conA));
    QVERIFY(disconnect(conA1));
    QVERIFY(disconnect(conA2));
    QVERIFY(disconnect(conB));
    QVERIFY(disconnect(conFinal));

#if defined(__cpp_return_type_deduction) && __cpp_return_type_deduction == 201304
    QVERIFY(receiverA.entered);
    QVERIFY(!receiverA.exited);
    QVERIFY(disconnect(aEntry));
    QVERIFY(disconnect(aExit));
#endif
}

class MyConnection : public Connection
{
    Q_OBJECT
public:
    MyConnection(QObject *parent = 0)
        : Connection(parent)
    {}
};

void tst_Compiled::myConnection()
{
    MyConnection stateMachine;

    Receiver receiverA;
    Receiver receiverA1;
    Receiver receiverA2;
    Receiver receiverB;
    Receiver receiverFinal;

    QMetaObject::Connection conA     = stateMachine.connectToState("a",     &receiverA,     SLOT(receive(bool)));
    QMetaObject::Connection conA1    = stateMachine.connectToState("a1",    &receiverA1,    SLOT(receive(bool)));
    QMetaObject::Connection conA2    = stateMachine.connectToState("a2",    &receiverA2,    SLOT(receive(bool)));
    QMetaObject::Connection conB     = stateMachine.connectToState("b",     &receiverB,     SLOT(receive(bool)));
    QMetaObject::Connection conFinal = stateMachine.connectToState("final", &receiverFinal, SLOT(receive(bool)));

    QVERIFY(conA);
    QVERIFY(conA1);
    QVERIFY(conA2);
    QVERIFY(conB);
    QVERIFY(conFinal);

    stateMachine.start();

    QTRY_VERIFY(receiverA.received);
    QTRY_VERIFY(receiverA1.received);
    QTRY_VERIFY(!receiverA2.received);
    QTRY_VERIFY(receiverB.received);
    QTRY_VERIFY(receiverFinal.received);

    QVERIFY(disconnect(conA));
    QVERIFY(disconnect(conA1));
    QVERIFY(disconnect(conA2));
    QVERIFY(disconnect(conB));
    QVERIFY(disconnect(conFinal));
}

void tst_Compiled::topMachine()
{
    TopMachine stateMachine;
    int doneCounter = 0;
    int invokableServicesCount = 0;

    stateMachine.connectToEvent("done.invoke.submachine", [&doneCounter](const QScxmlEvent &) {
        ++doneCounter;
    });

    QObject::connect(&stateMachine, &QScxmlStateMachine::invokedServicesChanged,
                     [&invokableServicesCount](const QVector<QScxmlInvokableService *> &services) {
        invokableServicesCount = services.count();
    });

    stateMachine.start();

    QTRY_COMPARE(invokableServicesCount, 3);
    QTRY_COMPARE(doneCounter, 3);
    QCOMPARE(stateMachine.invokedServices().count(), 3);
    QTRY_COMPARE(invokableServicesCount, 0);
}

void tst_Compiled::topMachineDynamic()
{
    QScopedPointer<QScxmlStateMachine> stateMachine(
                QScxmlStateMachine::fromFile(QString(":/topmachine.scxml")));
    QVERIFY(!stateMachine.isNull());
    int doneCounter = 0;
    int invokableServicesCount = 0;

    stateMachine->connectToEvent("done.invoke.submachine", [&doneCounter](const QScxmlEvent &) {
        ++doneCounter;
    });

    QObject::connect(stateMachine.data(), &QScxmlStateMachine::invokedServicesChanged,
                     [&invokableServicesCount](const QVector<QScxmlInvokableService *> &services) {
        invokableServicesCount = services.count();
    });

    stateMachine->start();

    QTRY_COMPARE(invokableServicesCount, 3);
    QTRY_COMPARE(doneCounter, 3);
    QCOMPARE(stateMachine->invokedServices().count(), 3);
    QTRY_COMPARE(invokableServicesCount, 0);
}

void tst_Compiled::publicSignals()
{
    const QMetaObject *connectionMeta = &Connection::staticMetaObject;
    int index = connectionMeta->indexOfSignal("aChanged(bool)");
    QVERIFY(index >= 0);

    QMetaMethod aChanged = connectionMeta->method(index);
    QVERIFY(aChanged.isValid());
    QCOMPARE(aChanged.access(), QMetaMethod::Public);
}

QTEST_MAIN(tst_Compiled)

#include "tst_compiled.moc"


