From edd63bd392ec870bea6bc7d37708b46320529c20 Mon Sep 17 00:00:00 2001
From: alexandr <alexandrmruchok@gmail.com>
Date: Mon, 19 Oct 2020 10:47:25 +0300
Subject: [PATCH] [+] DapGetNetworkStatusCommand; [+] DapNetwork::NAME, STATE,
 TARGET_STATE, NODE_ADDRESS, s_stateStrings, setProperties(), stringToState();
 [+] DapNetworksList::setNetworkProperties(), add(),networkAdded(),
 listCompositionChanged();

---
 chain/wallet/DapNetwork.cpp                   | 45 +++++++++++++---
 chain/wallet/DapNetwork.h                     | 14 ++++-
 .../handlers/DapGetNetworkStatusCommand.cpp   | 54 +++++++++++++++++++
 .../handlers/DapGetNetworkStatusCommand.h     | 30 +++++++++++
 chain/wallet/libdap-qt-chain-wallet.pri       |  2 +
 chain/wallet/models/DapNetworksList.cpp       | 28 ++++++++--
 chain/wallet/models/DapNetworksList.h         | 10 +++-
 7 files changed, 169 insertions(+), 14 deletions(-)
 create mode 100644 chain/wallet/handlers/DapGetNetworkStatusCommand.cpp
 create mode 100644 chain/wallet/handlers/DapGetNetworkStatusCommand.h

diff --git a/chain/wallet/DapNetwork.cpp b/chain/wallet/DapNetwork.cpp
index aeaf3e5a..d92d6200 100644
--- a/chain/wallet/DapNetwork.cpp
+++ b/chain/wallet/DapNetwork.cpp
@@ -1,4 +1,18 @@
 #include "DapNetwork.h"
+#include <QMap>
+#include <QJsonObject>
+#include <QDebug>
+
+const QString DapNetwork::NAME {"name"};
+const QString DapNetwork::STATE {"state"};
+const QString DapNetwork::TARGET_STATE {"targetState"};
+const QString DapNetwork::NODE_ADDRESS {"nodeAddress"};
+
+const QMap<DapNetwork::State, QString> DapNetwork::s_stateStrings = {
+    { DapNetwork::State::OFFLINE, "NET_STATE_OFFLINE"},
+    { DapNetwork::State::OFFLINE, "NET_STATE_ONLINE"}
+};
+
 
 DapNetwork::DapNetwork(const QString& a_name, QObject * a_parent /*= nullptr*/)
     : QObject(a_parent)
@@ -77,6 +91,23 @@ void DapNetwork::setState(DapNetwork::State a_state)
     emit this->stateChanged(DapNetwork::stateToString(a_state));
 }
 
+void DapNetwork::setProperties(QVariantMap a_stateMap)
+{
+    QJsonValue jsonValue;
+
+    if (a_stateMap.contains(STATE))
+        this->setTargetState(DapNetwork::stringToState(a_stateMap[STATE].toString()));
+
+    if (a_stateMap.contains(TARGET_STATE))
+        this->setTargetState(DapNetwork::stringToState(a_stateMap[TARGET_STATE].toString()));
+
+    if (this->nodeAddress().isEmpty()) //Is not necrssary to set node address if already set
+    {
+        if (a_stateMap.contains(NODE_ADDRESS))
+            this->setNodeAddress(a_stateMap[NODE_ADDRESS].toString());
+    }
+}
+
 DapNetwork::State DapNetwork::targetState() const
 {
     return m_targetState;
@@ -94,16 +125,16 @@ void DapNetwork::setTargetState(DapNetwork::State a_targetState)
     m_targetState = a_targetState;
 
     emit this->targetStateChanged(DapNetwork::stateToString(a_targetState));
-//    emit this->targetStateChanged(a_targetState);
+    //    emit this->targetStateChanged(a_targetState);
+}
+
+DapNetwork::State DapNetwork::stringToState(QString a_stateString)
+{
+    return s_stateStrings.key(a_stateString);
 }
 
 QString DapNetwork::stateToString(DapNetwork::State a_state)
 {
-    switch (a_state)
-    {
-        case State::Online: return "Online";
-        case State::Offline: return "Offline";
-        default: return {};
-    }
+    return s_stateStrings.value(a_state);
 }
 
diff --git a/chain/wallet/DapNetwork.h b/chain/wallet/DapNetwork.h
index 771d51ed..a45c73dc 100644
--- a/chain/wallet/DapNetwork.h
+++ b/chain/wallet/DapNetwork.h
@@ -8,10 +8,15 @@ class DapNetwork: public QObject
     Q_OBJECT
 public:
 
+    static const QString NAME;
+    static const QString STATE;
+    static const QString TARGET_STATE;
+    static const QString NODE_ADDRESS;
+
     enum State
     {
-        Online,
-        Offline
+        ONLINE,
+        OFFLINE
         //...
     };
 
@@ -40,11 +45,14 @@ public:
     State state() const;
     QString stateString() const;
     void setState(State a_state);
+    void setProperties(QVariantMap a_stateMap);
 
     State targetState() const;
     QString targetStateString() const;
     void setTargetState(State a_targetState);
 
+    State stringToState(QString a_stateString);
+
 signals:
     void nameChanged(const QString& a_name);
 
@@ -67,6 +75,8 @@ private:
     int m_linksCount{};
     int m_activeLinksCount{};
     QString m_nodeAddress;
+
+    static const QMap<State, QString> s_stateStrings;
 };
 
 Q_DECLARE_METATYPE(DapNetwork::State)
diff --git a/chain/wallet/handlers/DapGetNetworkStatusCommand.cpp b/chain/wallet/handlers/DapGetNetworkStatusCommand.cpp
new file mode 100644
index 00000000..56196b28
--- /dev/null
+++ b/chain/wallet/handlers/DapGetNetworkStatusCommand.cpp
@@ -0,0 +1,54 @@
+#include "DapGetNetworkStatusCommand.h"
+
+#include <QRegularExpression>
+
+/// Overloaded constructor.
+/// @param asServiceName Service name.
+/// @param parent Parent.
+/// @details The parent must be either DapRPCSocket or DapRPCLocalServer.
+/// @param asCliPath The path to cli nodes.
+DapGetNetworkStatusCommand::DapGetNetworkStatusCommand(const QString &asServicename, QObject *parent, const QString &asCliPath)
+    : DapAbstractCommand(asServicename, parent, asCliPath)
+{
+
+}
+
+/// Send a response to the client.
+/// @details Performed on the service side.
+/// @param arg1...arg10 Parameters.
+/// @return Reply to client.
+QVariant DapGetNetworkStatusCommand::respondToClient(const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4, const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8, const QVariant &arg9, const QVariant &arg10)
+{
+    Q_UNUSED(arg2)
+    Q_UNUSED(arg3)
+    Q_UNUSED(arg4)
+    Q_UNUSED(arg5)
+    Q_UNUSED(arg6)
+    Q_UNUSED(arg7)
+    Q_UNUSED(arg8)
+    Q_UNUSED(arg9)
+    Q_UNUSED(arg10)
+
+    QString network(arg1.toString());
+
+    QProcess process;
+    QString command(QString("%1 net -net %2 get status").arg(m_sCliPath).arg(arg1.toString()));
+    process.start(command);
+    process.waitForFinished(-1);
+    QString result = QString::fromLatin1(process.readAll());
+
+    QRegularExpression rx(R"(Network "\S+" has state (\S+) \(target state (\S*)\), cur node address ([A-F0-9]{4}::[A-F0-9]{4}::[A-F0-9]{4}::[A-F0-9]{4}))");
+    QRegularExpressionMatch match = rx.match(result);
+    if (!match.hasMatch()) {
+        return {};
+    }
+
+    QJsonObject returnValue({
+                                {"name"      , network},
+                                {"state"        , match.captured(1)},
+                                {"targetState"  , match.captured(2)},
+                                {"nodeAddress"  , match.captured(3)}
+                            });
+
+    return returnValue;
+}
diff --git a/chain/wallet/handlers/DapGetNetworkStatusCommand.h b/chain/wallet/handlers/DapGetNetworkStatusCommand.h
new file mode 100644
index 00000000..37c35824
--- /dev/null
+++ b/chain/wallet/handlers/DapGetNetworkStatusCommand.h
@@ -0,0 +1,30 @@
+#ifndef DAPGETNETWORKSTATUSCOMMAND_H
+#define DAPGETNETWORKSTATUSCOMMAND_H
+
+#include <QProcess>
+
+#include "DapAbstractCommand.h"
+
+class DapGetNetworkStatusCommand : public DapAbstractCommand
+{
+public:
+    /// Overloaded constructor.
+    /// @param asServiceName Service name.
+    /// @param parent Parent.
+    /// @details The parent must be either DapRPCSocket or DapRPCLocalServer.
+    /// @param asCliPath The path to cli nodes.
+    DapGetNetworkStatusCommand(const QString &asServicename, QObject *parent = nullptr, const QString &asCliPath = QString());
+
+public slots:
+    /// Send a response to the client.
+    /// @details Performed on the service side.
+    /// @param arg1...arg10 Parameters.
+    /// @return Reply to client.
+    QVariant respondToClient(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(),
+                             const QVariant &arg9 = QVariant(), const QVariant &arg10 = QVariant()) override;
+};
+
+#endif // DAPGETNETWORKSTATUSCOMMAND_H
diff --git a/chain/wallet/libdap-qt-chain-wallet.pri b/chain/wallet/libdap-qt-chain-wallet.pri
index ca70759c..87d46f64 100644
--- a/chain/wallet/libdap-qt-chain-wallet.pri
+++ b/chain/wallet/libdap-qt-chain-wallet.pri
@@ -34,6 +34,7 @@ HEADERS += \
     $$PWD/handlers/DapGetHistoryExecutedCmdCommand.h \
     $$PWD/handlers/DapGetListNetworksCommand.h \
     $$PWD/handlers/DapGetListWalletsCommand.h \
+    $$PWD/handlers/DapGetNetworkStatusCommand.h \
     $$PWD/handlers/DapGetWalletsInfoCommand.h \
     $$PWD/handlers/DapGetWalletAddressesCommand.h \
     $$PWD/handlers/DapGetWalletHistoryCommand.h \
@@ -72,6 +73,7 @@ SOURCES += \
     $$PWD/handlers/DapGetHistoryExecutedCmdCommand.cpp \
     $$PWD/handlers/DapGetListNetworksCommand.cpp \
     $$PWD/handlers/DapGetListWalletsCommand.cpp \
+    $$PWD/handlers/DapGetNetworkStatusCommand.cpp \
     $$PWD/handlers/DapGetWalletsInfoCommand.cpp \
     $$PWD/handlers/DapGetWalletAddressesCommand.cpp \
     $$PWD/handlers/DapGetWalletHistoryCommand.cpp \
diff --git a/chain/wallet/models/DapNetworksList.cpp b/chain/wallet/models/DapNetworksList.cpp
index 4c980098..c1189731 100644
--- a/chain/wallet/models/DapNetworksList.cpp
+++ b/chain/wallet/models/DapNetworksList.cpp
@@ -1,5 +1,6 @@
 #include "DapNetworksList.h"
 #include <QDebug>
+#include <QJsonObject>
 
 DapNetworksList::DapNetworksList(QObject *a_parrent /*= nullptr*/)
     :QObject(a_parrent)
@@ -28,6 +29,14 @@ DapNetwork *DapNetworksList::findNetwork(const QString &a_name)
     return *it;
 }
 
+
+
+void DapNetworksList::setNetworkProperties(QVariantMap a_networkState)
+{
+    DapNetwork* network = this->findNetwork(a_networkState.value(DapNetwork::NAME).toString());
+    network->setProperties(a_networkState);
+}
+
 void DapNetworksList::fill(QVariant a_stringList)
 {
     if (!a_stringList.isValid() || !a_stringList.canConvert<QStringList>())
@@ -36,14 +45,25 @@ void DapNetworksList::fill(QVariant a_stringList)
         return;
     }
 
+    bool netwarkAdded = false;
     for (QString curNetworkName: a_stringList.toStringList())
     {
         DapNetwork* network = this->findNetwork(curNetworkName);
         if (!network)
-        {
-            network = new DapNetwork(curNetworkName, this);
-            m_networks.append(network);
-            //TODO: get state
+        {           
+            this->add(curNetworkName);
+
+            netwarkAdded = true;
         }
     }
+
+    if (netwarkAdded)
+        emit this->listCompositionChanged();
+}
+
+void DapNetworksList::add(const QString &a_networkName)
+{
+    DapNetwork* newNetwork = new DapNetwork(a_networkName, this);
+    m_networks.append(newNetwork);
+    emit this->networkAdded(newNetwork);
 }
diff --git a/chain/wallet/models/DapNetworksList.h b/chain/wallet/models/DapNetworksList.h
index 164b421d..5381a345 100644
--- a/chain/wallet/models/DapNetworksList.h
+++ b/chain/wallet/models/DapNetworksList.h
@@ -11,15 +11,23 @@ public:
 
     DapNetworksList(QObject *a_parrent = nullptr);
 
-
     QList<QObject*> model();
 
     DapNetwork* findNetwork(const QString& a_name);
 
+    void setNetworkProperties(QVariantMap a_networkState);
+
 public slots:
     void fill(QVariant a_stringList);
 
+signals:
+    void networkAdded(DapNetwork* network);
+    void listCompositionChanged();
+
 private:
+    //If you call this method you need manually emit listCompositionChanged();
+    //Not required to emit listCompositionChanged every time when network added
+    void add(const QString& a_networkName);
     QList<DapNetwork*> m_networks;
 };
 
-- 
GitLab