1/*
2 * Copyright (c) 2023 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#ifndef OHOS_CALENDAR_NAPI_UTIL_H
16#define OHOS_CALENDAR_NAPI_UTIL_H
17#include <cstdint>
18#include <map>
19#include <variant>
20#include "calendar_define.h"
21#include "event_filter_napi.h"
22#include "napi/native_api.h"
23#include "napi/native_common.h"
24#include "napi/native_node_api.h"
25
26namespace OHOS::CalendarApi::NapiUtil {
27    napi_status GetValue(napi_env env, napi_value in, napi_value& out);
28    napi_status SetValue(napi_env env, napi_value in, napi_value& out);
29    /* napi_value <-> bool */
30    napi_status GetValue(napi_env env, napi_value in, bool& out);
31    napi_status SetValue(napi_env env, const bool& in, napi_value& out);
32
33    /* napi_value <-> int32_t */
34    napi_status GetValue(napi_env env, napi_value in, int32_t& out);
35    napi_status SetValue(napi_env env, const int32_t& in, napi_value& out);
36
37    /* napi_value <-> uint32_t */
38    napi_status GetValue(napi_env env, napi_value in, uint32_t& out);
39    napi_status SetValue(napi_env env, const uint32_t& in, napi_value& out);
40
41    /* napi_value <-> int64_t */
42    napi_status GetValue(napi_env env, napi_value in, int64_t& out);
43    napi_status SetValue(napi_env env, const int64_t& in, napi_value& out);
44
45    /* napi_value <-> uint64_t */
46    napi_status GetValue(napi_env env, napi_value in, uint64_t& out);
47    napi_status SetValue(napi_env env, const uint64_t& in, napi_value& out);
48
49    /* napi_value <-> double */
50    napi_status GetValue(napi_env env, napi_value in, double& out);
51    napi_status SetValue(napi_env env, const double& in, napi_value& out);
52
53    /* napi_value <-> std::string */
54    napi_status GetValue(napi_env env, napi_value in, std::string& out);
55    napi_status SetValue(napi_env env, const std::string& in, napi_value& out);
56
57    /* napi_value <-> std::vector<std::string> */
58    napi_status GetValue(napi_env env, napi_value in, std::vector<std::string>& out);
59    napi_status SetValue(napi_env env, const std::vector<std::string>& in, napi_value& out);
60
61    /* napi_value <-> std::vector<uint8_t> */
62    napi_status GetValue(napi_env env, napi_value in, std::vector<uint8_t>& out);
63    napi_status SetValue(napi_env env, const std::vector<uint8_t>& in, napi_value& out);
64
65    /* napi_value <-> std::vector<int32_t> */
66    napi_status GetValue(napi_env env, napi_value in, std::vector<int32_t>& out);
67    napi_status SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out);
68
69    /* napi_value <-> std::vector<uint32_t> */
70    napi_status GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out);
71    napi_status SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out);
72
73    /* napi_value <-> std::vector<int64_t> */
74    napi_status GetValue(napi_env env, napi_value in, std::vector<int64_t>& out);
75    napi_status SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out);
76
77    /* napi_value <-> std::vector<double> */
78    napi_status GetValue(napi_env env, napi_value in, std::vector<double>& out);
79    napi_status SetValue(napi_env env, const std::vector<double>& in, napi_value& out);
80
81    /* napi_value <-> CalendarAccount */
82    napi_status GetValue(napi_env env, napi_value in, CalendarAccount& out);
83    napi_status SetValue(napi_env env, const CalendarAccount& in, napi_value& out);
84
85    /* napi_value <-> CalendarConfig */
86    napi_status GetValue(napi_env env, napi_value in, CalendarConfig& out);
87    napi_status SetValue(napi_env env, const CalendarConfig& in, napi_value& out);
88
89    /* napi_value <-> Location */
90    napi_status GetValue(napi_env env, napi_value in, Location& out);
91    napi_status SetValue(napi_env env, const Location& in, napi_value& out);
92
93    /* napi_value <-> RecurrenceRule */
94    napi_status GetValue(napi_env env, napi_value in, RecurrenceRule& out);
95    napi_status SetValue(napi_env env, const RecurrenceRule& in, napi_value& out);
96
97    /* napi_value <-> Attendee */
98    napi_status GetValue(napi_env env, napi_value in, Attendee& out);
99    napi_status SetValue(napi_env env, const Attendee& in, napi_value& out);
100
101    /* napi_value <-> std::vector<Attendee> */
102    napi_status GetValue(napi_env env, napi_value in, std::vector<Attendee>& out);
103    napi_status SetValue(napi_env env, const std::vector<Attendee>& in, napi_value& out);
104
105    /* napi_value <-> EventService */
106    napi_status GetValue(napi_env env, napi_value in, EventService& out);
107    napi_status SetValue(napi_env env, const EventService& in, napi_value& out);
108
109    /* napi_value <-> EventFilter */
110    napi_status GetValue(napi_env env, napi_value in, EventFilterNapi*& out);
111    napi_status SetValue(napi_env env, const EventFilterNapi& in, napi_value& out);
112
113    /* napi_value <-> EventType */
114    napi_status GetValue(napi_env env, napi_value in, EventType& out);
115    napi_status SetValue(napi_env env, const EventType& in, napi_value& out);
116
117    /* napi_value <-> Event */
118    napi_status GetValue(napi_env env, napi_value in, Event& out);
119    napi_status SetValue(napi_env env, const Event& in, napi_value& out);
120
121    /* napi_value <-> std::vector<Event> */
122    napi_status GetValue(napi_env env, napi_value in, std::vector<Event>& out);
123    napi_status SetValue(napi_env env, const std::vector<Event>& in, napi_value& out);
124
125    /* napi_get_named_property wrapper */
126    template <typename T>
127    napi_status GetNamedProperty(napi_env env, napi_value in, const std::string& prop, T& value)
128    {
129        bool hasProp = false;
130        napi_status status = napi_has_named_property(env, in, prop.c_str(), &hasProp);
131        if ((status == napi_ok) && hasProp) {
132            napi_value inner = nullptr;
133            status = napi_get_named_property(env, in, prop.c_str(), &inner);
134            if ((status == napi_ok) && (inner != nullptr)) {
135                return GetValue(env, inner, value);
136            }
137        }
138        return napi_invalid_arg;
139    };
140
141    template <typename T>
142    napi_status SetNamedProperty(napi_env env, const string& prop, const T&nativeValue, napi_value& out)
143    {
144        napi_value value = nullptr;
145        auto status = SetValue(env, nativeValue, value);
146        if (status != napi_ok) {
147            return status;
148        }
149        return napi_set_named_property(env, out, prop.c_str(), value);
150    }
151
152    template <typename T>
153    void SetNamedPropertyOptional(napi_env env, const string& prop, const std::optional<T>&nativeValue, napi_value& out)
154    {
155        if (!nativeValue) {
156            return;
157        }
158        napi_value value = nullptr;
159        auto status = SetValue(env, nativeValue.value(), value);
160        if (status != napi_ok) {
161            return;
162        }
163        napi_set_named_property(env, out, prop.c_str(), value);
164    }
165
166    /* napi_get_named_property wrapper */
167    template <typename T>
168    void GetNamedPropertyOptional(napi_env env, napi_value in, const std::string& prop, std::optional<T>& out)
169    {
170        bool hasProp = false;
171        napi_status status = napi_has_named_property(env, in, prop.c_str(), &hasProp);
172        if ((status != napi_ok) || !hasProp) {
173            out = std::nullopt;
174            return;
175        }
176        napi_value inner = nullptr;
177        status = napi_get_named_property(env, in, prop.c_str(), &inner);
178        if ((status != napi_ok) || (inner == nullptr)) {
179            out = std::nullopt;
180            return;
181        }
182        T value;
183        status = GetValue(env, inner, value);
184        if (status != napi_ok) {
185            out = std::nullopt;
186            return;
187        }
188        out = value;
189    };
190
191    /* napi_value <-> std::vector<T> */
192    template <typename T>
193    napi_status SetValueArray(napi_env env, const std::vector<T>& in, napi_value& out)
194    {
195        napi_status status = napi_create_array_with_length(env, in.size(), &out);
196        if (status != napi_ok) {
197            return status;
198        }
199        int index = 0;
200        for (auto& item : in) {
201            napi_value element = nullptr;
202            SetValue(env, item, element);
203            status = napi_set_element(env, out, index++, element);
204            if (status != napi_ok) {
205                return status;
206            }
207        }
208        return status;
209    }
210
211    /* napi_value <-> std::vector<T> */
212    template <typename T>
213    napi_status GetValueArray(napi_env env, napi_value in, std::vector<T>& out)
214    {
215        out.clear();
216        bool isArray = false;
217        napi_is_array(env, in, &isArray);
218        if (!isArray) {
219            return napi_invalid_arg;
220        }
221
222        uint32_t length = 0;
223        napi_status status = napi_get_array_length(env, in, &length);
224        if (status != napi_ok || length <= 0) {
225            return napi_invalid_arg;
226        }
227        for (uint32_t i = 0; i < length; i++) {
228            napi_value item = nullptr;
229            status = napi_get_element(env, in, i, &item);
230            if (item == nullptr || status != napi_ok) {
231                return napi_invalid_arg;
232            }
233            T outItem;
234            GetValue(env, item, outItem);
235            out.push_back(outItem);
236        }
237        return status;
238    }
239
240    /* napi_define_class  wrapper */
241    napi_value DefineClass(napi_env env, const std::string& name,
242        const napi_property_descriptor* properties, size_t count, napi_callback newcb);
243
244    /* napi_new_instance  wrapper */
245    napi_ref NewWithRef(napi_env env, size_t argc, napi_value* argv, void** out, napi_value constructor);
246
247    /* napi_unwrap with napi_instanceof */
248    napi_status Unwrap(napi_env env, napi_value in, void** out, napi_value constructor);
249
250    bool Equals(napi_env env, napi_value value, napi_ref copy);
251
252} // namespace OHOS::CalendarApi::NapiUtil
253#endif // OHOS_CALENDAR_NAPI_UTIL_H
254