10fbfc30aSopenharmony_ci/*
20fbfc30aSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
30fbfc30aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40fbfc30aSopenharmony_ci * you may not use this file except in compliance with the License.
50fbfc30aSopenharmony_ci * You may obtain a copy of the License at
60fbfc30aSopenharmony_ci *
70fbfc30aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
80fbfc30aSopenharmony_ci *
90fbfc30aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100fbfc30aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110fbfc30aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120fbfc30aSopenharmony_ci * See the License for the specific language governing permissions and
130fbfc30aSopenharmony_ci * limitations under the License.
140fbfc30aSopenharmony_ci */
150fbfc30aSopenharmony_ci#ifndef CALENDAR_MANAGER_NAPI_QUEUE_H
160fbfc30aSopenharmony_ci#define CALENDAR_MANAGER_NAPI_QUEUE_H
170fbfc30aSopenharmony_ci#include <functional>
180fbfc30aSopenharmony_ci#include <memory>
190fbfc30aSopenharmony_ci#include <string>
200fbfc30aSopenharmony_ci
210fbfc30aSopenharmony_ci#include "calendar_log.h"
220fbfc30aSopenharmony_ci#include "napi/native_api.h"
230fbfc30aSopenharmony_ci#include "napi/native_common.h"
240fbfc30aSopenharmony_ci#include "napi/native_node_api.h"
250fbfc30aSopenharmony_ci
260fbfc30aSopenharmony_cinamespace OHOS::CalendarApi {
270fbfc30aSopenharmony_ciconstexpr size_t ARGC_MAX = 6;
280fbfc30aSopenharmony_ciusing NapiCbInfoParser = std::function<void(size_t argc, napi_value* argv)>;
290fbfc30aSopenharmony_ciusing NapiAsyncExecute = std::function<void(void)>;
300fbfc30aSopenharmony_ciusing NapiAsyncComplete = std::function<void(napi_value&)>;
310fbfc30aSopenharmony_ci
320fbfc30aSopenharmony_cistruct ContextBase {
330fbfc30aSopenharmony_ci    virtual ~ContextBase();
340fbfc30aSopenharmony_ci    void GetCbInfo(napi_env env, napi_callback_info info,
350fbfc30aSopenharmony_ci                   NapiCbInfoParser parse = NapiCbInfoParser(), bool sync = false);
360fbfc30aSopenharmony_ci
370fbfc30aSopenharmony_ci    inline void GetCbInfoSync(napi_env env, napi_callback_info info, NapiCbInfoParser parse = NapiCbInfoParser())
380fbfc30aSopenharmony_ci    {
390fbfc30aSopenharmony_ci        GetCbInfo(env, info, parse, true);
400fbfc30aSopenharmony_ci    }
410fbfc30aSopenharmony_ci
420fbfc30aSopenharmony_ci    napi_env env = nullptr;
430fbfc30aSopenharmony_ci    napi_value output = nullptr;
440fbfc30aSopenharmony_ci    napi_status status = napi_invalid_arg;
450fbfc30aSopenharmony_ci    std::string error;
460fbfc30aSopenharmony_ci
470fbfc30aSopenharmony_ci    napi_value self = nullptr;
480fbfc30aSopenharmony_ci    void* native = nullptr;
490fbfc30aSopenharmony_ci
500fbfc30aSopenharmony_ciprivate:
510fbfc30aSopenharmony_ci    napi_ref callbackRef = nullptr;
520fbfc30aSopenharmony_ci    napi_ref selfRef = nullptr;
530fbfc30aSopenharmony_ci    friend class NapiQueue;
540fbfc30aSopenharmony_ci};
550fbfc30aSopenharmony_ci
560fbfc30aSopenharmony_ci/* check condition related to argc/argv, return and logging. */
570fbfc30aSopenharmony_ci#define CHECK_ARGS_RETURN_VOID(ctxt, condition, message)                    \
580fbfc30aSopenharmony_ci    do {                                                                    \
590fbfc30aSopenharmony_ci        if (!(condition)) {                                                 \
600fbfc30aSopenharmony_ci            (ctxt)->status = napi_invalid_arg;                              \
610fbfc30aSopenharmony_ci            (ctxt)->error = std::string(message);                           \
620fbfc30aSopenharmony_ci            LOG_ERROR("test (" #condition ") failed: " message);            \
630fbfc30aSopenharmony_ci            return;                                                         \
640fbfc30aSopenharmony_ci        }                                                                   \
650fbfc30aSopenharmony_ci    } while (0)
660fbfc30aSopenharmony_ci
670fbfc30aSopenharmony_ci#define CHECK_STATUS_RETURN_VOID(ctxt, message)                        \
680fbfc30aSopenharmony_ci    do {                                                               \
690fbfc30aSopenharmony_ci        if ((ctxt)->status != napi_ok) {                               \
700fbfc30aSopenharmony_ci            (ctxt)->error = std::string(message);                      \
710fbfc30aSopenharmony_ci            LOG_ERROR("test (ctxt->status %{public}d) failed: " message, (ctxt)->status);  \
720fbfc30aSopenharmony_ci            return;                                                    \
730fbfc30aSopenharmony_ci        }                                                              \
740fbfc30aSopenharmony_ci    } while (0)
750fbfc30aSopenharmony_ci
760fbfc30aSopenharmony_ci/* check condition, return and logging if condition not true. */
770fbfc30aSopenharmony_ci#define CHECK_RETURN(condition, message, retVal)             \
780fbfc30aSopenharmony_ci    do {                                                     \
790fbfc30aSopenharmony_ci        if (!(condition)) {                                  \
800fbfc30aSopenharmony_ci            LOG_ERROR("test (" #condition ") failed: " message); \
810fbfc30aSopenharmony_ci            return retVal;                                   \
820fbfc30aSopenharmony_ci        }                                                    \
830fbfc30aSopenharmony_ci    } while (0)
840fbfc30aSopenharmony_ci
850fbfc30aSopenharmony_ci#define CHECK_RETURN_VOID(condition, message)                \
860fbfc30aSopenharmony_ci    do {                                                     \
870fbfc30aSopenharmony_ci        if (!(condition)) {                                  \
880fbfc30aSopenharmony_ci            LOG_ERROR("test (" #condition ") failed: " message); \
890fbfc30aSopenharmony_ci            return;                                          \
900fbfc30aSopenharmony_ci        }                                                    \
910fbfc30aSopenharmony_ci    } while (0)
920fbfc30aSopenharmony_ci
930fbfc30aSopenharmony_ciclass NapiQueue {
940fbfc30aSopenharmony_cipublic:
950fbfc30aSopenharmony_ci    static napi_value AsyncWork(napi_env env, std::shared_ptr<ContextBase> ctxt,
960fbfc30aSopenharmony_ci                                const std::string& name, NapiAsyncExecute execute = NapiAsyncExecute(),
970fbfc30aSopenharmony_ci                                NapiAsyncComplete complete = NapiAsyncComplete());
980fbfc30aSopenharmony_ci
990fbfc30aSopenharmony_ciprivate:
1000fbfc30aSopenharmony_ci    enum {
1010fbfc30aSopenharmony_ci        RESULT_ERROR = 0,
1020fbfc30aSopenharmony_ci        RESULT_DATA = 1,
1030fbfc30aSopenharmony_ci        RESULT_ALL = 2
1040fbfc30aSopenharmony_ci    };
1050fbfc30aSopenharmony_ci
1060fbfc30aSopenharmony_ci    struct AsyncContext {
1070fbfc30aSopenharmony_ci        napi_env env = nullptr;
1080fbfc30aSopenharmony_ci        std::shared_ptr<ContextBase> ctx;
1090fbfc30aSopenharmony_ci        NapiAsyncExecute execute = nullptr;
1100fbfc30aSopenharmony_ci        NapiAsyncComplete complete = nullptr;
1110fbfc30aSopenharmony_ci        napi_deferred deferred = nullptr;
1120fbfc30aSopenharmony_ci        napi_async_work work = nullptr;
1130fbfc30aSopenharmony_ci        ~AsyncContext()
1140fbfc30aSopenharmony_ci        {
1150fbfc30aSopenharmony_ci            execute = nullptr;
1160fbfc30aSopenharmony_ci            complete = nullptr;
1170fbfc30aSopenharmony_ci            ctx = nullptr;
1180fbfc30aSopenharmony_ci            if (env != nullptr) {
1190fbfc30aSopenharmony_ci                if (work != nullptr) {
1200fbfc30aSopenharmony_ci                    napi_delete_async_work(env, work);
1210fbfc30aSopenharmony_ci                }
1220fbfc30aSopenharmony_ci            }
1230fbfc30aSopenharmony_ci        }
1240fbfc30aSopenharmony_ci    };
1250fbfc30aSopenharmony_ci    static void GenerateOutput(AsyncContext &ctx, napi_value output);
1260fbfc30aSopenharmony_ci};
1270fbfc30aSopenharmony_ci} // namespace Calendar::CalendarApi
1280fbfc30aSopenharmony_ci#endif