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 "module_template.h"
17#include "netmanager_base_log.h"
18
19#include <algorithm>
20
21namespace OHOS {
22namespace NetManagerStandard {
23namespace ModuleTemplate {
24namespace {
25static constexpr const int EVENT_PARAM_NUM = 2;
26} // namespace
27
28napi_value On(napi_env env, napi_callback_info info, const std::initializer_list<std::string> &events,
29              bool asyncCallback)
30{
31    napi_value thisVal = nullptr;
32    size_t paramsCount = MAX_PARAM_NUM;
33    napi_value params[MAX_PARAM_NUM] = {nullptr};
34    NAPI_CALL(env, napi_get_cb_info(env, info, &paramsCount, params, &thisVal, nullptr));
35
36    if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string ||
37        NapiUtils::GetValueType(env, params[1]) != napi_function) {
38        NETMANAGER_BASE_LOGE("napi on interface para: [string, function]");
39        return NapiUtils::GetUndefined(env);
40    }
41
42    std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
43    if (std::find(events.begin(), events.end(), event) == events.end()) {
44        return NapiUtils::GetUndefined(env);
45    }
46
47    EventManager *manager = nullptr;
48    napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
49    if (manager != nullptr) {
50        manager->AddListener(env, event, params[1], false, asyncCallback);
51    }
52
53    return NapiUtils::GetUndefined(env);
54}
55
56napi_value Once(napi_env env, napi_callback_info info, const std::initializer_list<std::string> &events,
57                bool asyncCallback)
58{
59    napi_value thisVal = nullptr;
60    size_t paramsCount = MAX_PARAM_NUM;
61    napi_value params[MAX_PARAM_NUM] = {nullptr};
62    NAPI_CALL(env, napi_get_cb_info(env, info, &paramsCount, params, &thisVal, nullptr));
63
64    if (paramsCount != EVENT_PARAM_NUM || NapiUtils::GetValueType(env, params[0]) != napi_string ||
65        NapiUtils::GetValueType(env, params[1]) != napi_function) {
66        NETMANAGER_BASE_LOGE("napi once interface para: [string, function]");
67        return NapiUtils::GetUndefined(env);
68    }
69
70    std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
71    if (std::find(events.begin(), events.end(), event) == events.end()) {
72        return NapiUtils::GetUndefined(env);
73    }
74
75    EventManager *manager = nullptr;
76    napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
77    if (manager != nullptr) {
78        manager->AddListener(env, event, params[1], true, asyncCallback);
79    }
80
81    return NapiUtils::GetUndefined(env);
82}
83
84napi_value Off(napi_env env, napi_callback_info info, const std::initializer_list<std::string> &events)
85{
86    napi_value thisVal = nullptr;
87    size_t paramsCount = MAX_PARAM_NUM;
88    napi_value params[MAX_PARAM_NUM] = {nullptr};
89    NAPI_CALL(env, napi_get_cb_info(env, info, &paramsCount, params, &thisVal, nullptr));
90
91    if ((paramsCount != 1 && paramsCount != EVENT_PARAM_NUM) ||
92        NapiUtils::GetValueType(env, params[0]) != napi_string) {
93        NETMANAGER_BASE_LOGE("napi off interface para: [string, function?]");
94        return NapiUtils::GetUndefined(env);
95    }
96
97    if (paramsCount == EVENT_PARAM_NUM && NapiUtils::GetValueType(env, params[1]) != napi_function) {
98        NETMANAGER_BASE_LOGE("napi off interface para: [string, function]");
99        return NapiUtils::GetUndefined(env);
100    }
101
102    std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
103    if (std::find(events.begin(), events.end(), event) == events.end()) {
104        return NapiUtils::GetUndefined(env);
105    }
106
107    EventManager *manager = nullptr;
108    napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
109    if (manager != nullptr) {
110        if (paramsCount == EVENT_PARAM_NUM) {
111            manager->DeleteListener(event, params[1]);
112        } else {
113            manager->DeleteListener(event);
114        }
115    }
116
117    return NapiUtils::GetUndefined(env);
118}
119
120void DefineClass(napi_env env, napi_value exports, const std::initializer_list<napi_property_descriptor> &properties,
121                 const std::string &className)
122{
123    auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
124        napi_value thisVal = nullptr;
125        NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
126
127        return thisVal;
128    };
129
130    napi_value jsConstructor = nullptr;
131
132    napi_property_descriptor descriptors[properties.size()];
133    std::copy(properties.begin(), properties.end(), descriptors);
134
135    NAPI_CALL_RETURN_VOID(env, napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, constructor, nullptr,
136                                                 properties.size(), descriptors, &jsConstructor));
137
138    NapiUtils::SetNamedProperty(env, exports, className, jsConstructor);
139}
140
141napi_value NewInstance(napi_env env, napi_callback_info info, const std::string &className,
142                       void *(*MakeData)(napi_env, size_t, napi_value *, EventManager *), Finalizer finalizer)
143{
144    napi_value thisVal = nullptr;
145    std::size_t argc = MAX_PARAM_NUM;
146    napi_value argv[MAX_PARAM_NUM] = {nullptr};
147    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
148
149    napi_value jsConstructor = NapiUtils::GetNamedProperty(env, thisVal, className);
150    if (NapiUtils::GetValueType(env, jsConstructor) == napi_undefined) {
151        return nullptr;
152    }
153
154    napi_value result = nullptr;
155    NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
156
157    auto manager = new EventManager();
158    if (MakeData != nullptr) {
159        auto data = MakeData(env, argc, argv, manager);
160        if (data == nullptr) {
161            return NapiUtils::GetUndefined(env);
162        }
163        manager->SetData(data);
164    }
165    napi_wrap(env, result, reinterpret_cast<void *>(manager), finalizer, nullptr, nullptr);
166
167    return result;
168}
169} // namespace ModuleTemplate
170} // namespace NetManagerStandard
171} // namespace OHOS
172