1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "tcp_socket_manager.h"
17
18#include <QJsonDocument>
19#include <QJsonObject>
20#include <QJsonArray>
21
22#include "auto_test_manager.h"
23
24namespace OHOS {
25static void StartTest(std::vector<std::shared_ptr<TestMsgInfo>> msgInfo)
26{
27    AutoTestManager::GetInstance()->StartTest(msgInfo);
28}
29
30static void DipatchConfigMsg(std::shared_ptr<TestConfigInfo> configInfo)
31{
32    AutoTestManager::GetInstance()->SetConfigInfo(configInfo);
33}
34
35static void DispatchComplete()
36{
37    AutoTestManager::GetInstance()->TestComplete();
38}
39
40static void SendTestMsg(size_t mainID)
41{
42    TcpSocketClientManager::GetInstance()->SendMsg(mainID);
43}
44
45TcpSocketClientManager* TcpSocketClientManager::GetInstance()
46{
47    static TcpSocketClientManager instance;
48    return &instance;
49}
50
51TcpSocketClientManager::~TcpSocketClientManager()
52{
53    if (tcpSocket_) {
54        delete tcpSocket_;
55    }
56}
57
58void TcpSocketClientManager::InitSocket()
59{
60    if (tcpSocket_ == nullptr) {
61        tcpSocket_ = new TcpScoketClient();
62    }
63
64    tcpSocket_->CreateTCPScoket();
65    tcpSocket_->SetScoketManager(GetInstance());
66
67    ConnectSocket();
68
69    SetDispatchFuncCallBack(std::bind(StartTest, std::placeholders::_1));
70    SetDispatchConfigFuncCallBack(std::bind(DipatchConfigMsg, std::placeholders::_1));
71    SetDispatchCompleteFuncCallBack(std::bind(DispatchComplete));
72    AutoTestManager::GetInstance()->SetSendMsgFuncCallBack(std::bind(SendTestMsg, std::placeholders::_1));
73}
74
75void TcpSocketClientManager::ConnectSocket()
76{
77    if (tcpSocket_ == nullptr) {
78        return;
79    }
80
81    tcpSocket_->ConnectSocket();
82}
83
84void TcpSocketClientManager::OnGetEventValue(QJsonArray array, std::vector<int>& values)
85{
86    foreach (auto it, array) {
87        values.push_back(it.toInt());
88    }
89}
90
91void TcpSocketClientManager::OnGetPageNav(QJsonArray array, std::vector<std::string>& pageNav)
92{
93    foreach (auto it, array) {
94        pageNav.push_back(it.toString().toStdString());
95    }
96}
97
98void TcpSocketClientManager::OnGetTestSetps(QJsonArray array, std::vector<TestSteps>& steps)
99{
100    foreach (auto it, array) {
101        TestSteps testSteps;
102        QJsonObject arrobj = it.toObject();
103        if (arrobj.contains(JSON_VALUE_VIEW_ID.c_str())) {
104            testSteps.viewID = arrobj.value(JSON_VALUE_VIEW_ID.c_str()).toString().toStdString();
105        }
106        if (arrobj.contains(JSON_VALUE_EVENT_ID.c_str())) {
107            testSteps.eventID = static_cast<TestEventID>(arrobj.value(JSON_VALUE_EVENT_ID.c_str()).toInt());
108        }
109        if (arrobj.contains(JSON_VALUE_EVENT_VALUE.c_str())) {
110            QJsonValue arrays_value = arrobj.take(JSON_VALUE_EVENT_VALUE.c_str());
111            if (arrays_value.isArray()) {
112                QJsonArray localArray = arrays_value.toArray();
113                OnGetEventValue(localArray, testSteps.eventValue);
114            }
115        }
116        if (arrobj.contains(JSON_VALUE_SAVE_CHECK_POINT.c_str())) {
117            testSteps.saveCheckPoint = static_cast<bool>(
118                arrobj.value(JSON_VALUE_SAVE_CHECK_POINT.c_str()).toBool());
119        }
120        steps.push_back(testSteps);
121    }
122}
123
124void TcpSocketClientManager::RecvMsg(QByteArray recv)
125{
126    std::shared_ptr<QByteArray> recvmsg = std::make_shared<QByteArray>(recv);
127    QMutexLocker mutexLocker(&mutex_);
128    recv_.push_back(recvmsg);
129}
130
131void TcpSocketClientManager::OnGetMsgInfo(const std::shared_ptr<QByteArray> recv)
132{
133    QJsonParseError parseError;
134    QJsonDocument document = QJsonDocument::fromJson(recv->toStdString().data(), &parseError);
135    if (parseError.error != QJsonParseError::NoError) {
136        return;
137    }
138
139    QJsonObject object;
140    if (document.isObject()) {
141        object = document.object();
142    }
143
144    size_t mainID = 0;
145    if (object.contains(JSON_VALUE_MAIN_ID.c_str())) {
146        mainID = static_cast<size_t>(object.value(JSON_VALUE_MAIN_ID.c_str()).toInt());
147    }
148
149    printf("OnGetMsgInfo------mainID = [%zu]\n", mainID);
150    fflush(stdout);
151    switch (mainID) {
152        case S_C_MAIN_ID_SEND_CONFIG_INFO:
153            OnGetConfigInfo(object);
154            break;
155        case S_C_MAIN_ID_SEND_TEST_INFO:
156            OnGetTestInfo(object);
157            break;
158        case S_C_MAIN_ID_All_TESTS_COMPLETE:
159            dispatchCompleteFunc_();
160            break;
161        default:
162            break;
163    }
164}
165
166void TcpSocketClientManager::OnGetConfigInfo(const QJsonObject object)
167{
168    if (object.empty()) {
169        return;
170    }
171
172    std::shared_ptr<TestConfigInfo> configInfo = std::make_shared<TestConfigInfo>();
173    if (object.contains(JOSN_VALUE_TEST_MODE.c_str())) {
174        configInfo->testMode = static_cast<TestMode>(object.value(JOSN_VALUE_TEST_MODE.c_str()).toInt());
175    }
176
177    if (object.contains(JSON_VALUE_BASE_DIR.c_str())) {
178        configInfo->baseDir =  object.value(JSON_VALUE_BASE_DIR.c_str()).toString().toStdString();
179    }
180
181    if (object.contains(JSON_VALUE_RUN_DIR.c_str())) {
182        configInfo->runDir =  object.value(JSON_VALUE_RUN_DIR.c_str()).toString().toStdString();
183    }
184
185    if (object.contains(JSON_VALUE_LOG_DIR.c_str())) {
186        configInfo->logDir =  object.value(JSON_VALUE_LOG_DIR.c_str()).toString().toStdString();
187    }
188
189    dispatchConfigFunc_(configInfo);
190}
191
192void TcpSocketClientManager::OnGetTestInfo(QJsonObject object)
193{
194    if (object.empty()) {
195        return;
196    }
197
198    std::vector<std::shared_ptr<TestMsgInfo>> testMsgInfo;
199    if (object.contains(JSON_VALUE_TEST_INFO.c_str())) {
200        QJsonValue arrays_value = object.take(JSON_VALUE_TEST_INFO.c_str());
201        if (!arrays_value.isArray()) {
202            return;
203        }
204
205        QJsonArray assintArray = arrays_value.toArray();
206        foreach(auto it, assintArray) {
207            std::shared_ptr<TestMsgInfo> msgInfo = std::make_shared<TestMsgInfo>();
208            QJsonObject arrobj = it.toObject();
209            OnGetTestInfo(arrobj, msgInfo);
210            testMsgInfo.push_back(msgInfo);
211        }
212    }
213    OnPrintTestInfo(testMsgInfo);
214
215    dispatchFunc_(testMsgInfo);
216}
217
218void TcpSocketClientManager::OnGetTestInfo(QJsonObject arrobj, std::shared_ptr<TestMsgInfo>& msgInfo)
219{
220    if (arrobj.contains(JSON_VALUE_CLASS_NAME.c_str())) {
221        msgInfo->className = arrobj.value(JSON_VALUE_CLASS_NAME.c_str()).toString().toStdString();
222    }
223
224    if (arrobj.contains(JSON_VALUE_PAGE_NAV.c_str())) {
225        QJsonValue value = arrobj.take(JSON_VALUE_PAGE_NAV.c_str());
226        if (value.isArray()) {
227            QJsonArray array = value.toArray();
228            OnGetPageNav(array, msgInfo->pageNav);
229        }
230    }
231
232    if (arrobj.contains(JSON_VALUE_TEST_STEPS.c_str())) {
233        QJsonValue value = arrobj.take(JSON_VALUE_TEST_STEPS.c_str());
234        if (value.isArray()) {
235            QJsonArray array = value.toArray();
236            OnGetTestSetps(array, msgInfo->steps);
237        }
238    }
239}
240
241void TcpSocketClientManager::OnPrintTestInfo(const std::vector<std::shared_ptr<TestMsgInfo>> testMsgInfo) const
242{
243    for (auto it : testMsgInfo) {
244        printf("TcpSocketClientManager::OnRunRecvMsg()-className=[%s],---\n", it->className.c_str());
245        fflush(stdout);
246        for (auto it2 : it->pageNav) {
247            printf("pageNav--%s----------", it2.c_str());
248        }
249        printf("\n");
250        for (auto it3: it->steps) {
251            printf("steps---viewID=[%s], eventID=[%d]", it3.viewID.c_str(), it3.eventID);
252            for (auto it4 : it3.eventValue) {
253                printf("steps---eventValue=[%d]", it4);
254            }
255            printf("steps---saveCheckPoint=[%d]--------\n", it3.saveCheckPoint);
256        }
257    }
258}
259
260void TcpSocketClientManager::DispatchMsg()
261{
262    OnRunRecvMsg();
263}
264
265void TcpSocketClientManager::SetDispatchFuncCallBack(DispatchFunc dispatchFunc)
266{
267    dispatchFunc_ = dispatchFunc;
268}
269
270void TcpSocketClientManager::SetDispatchConfigFuncCallBack(DispatchConfigFunc dispatchConfigFunc)
271{
272    dispatchConfigFunc_ = dispatchConfigFunc;
273}
274
275void TcpSocketClientManager::SetDispatchCompleteFuncCallBack(DispatchCompleteFunc dispatchCompleteFunc)
276{
277    dispatchCompleteFunc_ = dispatchCompleteFunc;
278}
279
280void TcpSocketClientManager::OnRunRecvMsg()
281{
282    if (recv_.empty()) {
283        return;
284    }
285
286    QMutexLocker mutexLocker(&mutex_);
287    std::shared_ptr<QByteArray> recv = recv_.front();
288    recv_.pop_front();
289
290    OnGetMsgInfo(recv);
291}
292} // namespace OHOS
293