1ce968135Sopenharmony_ci/*
2ce968135Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3ce968135Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ce968135Sopenharmony_ci * you may not use this file except in compliance with the License.
5ce968135Sopenharmony_ci * You may obtain a copy of the License at
6ce968135Sopenharmony_ci *
7ce968135Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ce968135Sopenharmony_ci *
9ce968135Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ce968135Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ce968135Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ce968135Sopenharmony_ci * See the License for the specific language governing permissions and
13ce968135Sopenharmony_ci * limitations under the License.
14ce968135Sopenharmony_ci */
15ce968135Sopenharmony_ci#ifndef WALLPAPER_CALL_H
16ce968135Sopenharmony_ci#define WALLPAPER_CALL_H
17ce968135Sopenharmony_ci
18ce968135Sopenharmony_ci#include <functional>
19ce968135Sopenharmony_ci#include <memory>
20ce968135Sopenharmony_ci
21ce968135Sopenharmony_ci#include "napi/native_api.h"
22ce968135Sopenharmony_ci#include "napi/native_common.h"
23ce968135Sopenharmony_ci#include "napi/native_node_api.h"
24ce968135Sopenharmony_ci
25ce968135Sopenharmony_cinamespace OHOS::WallpaperNAPI {
26ce968135Sopenharmony_ciclass Call final {
27ce968135Sopenharmony_cipublic:
28ce968135Sopenharmony_ci    class Context {
29ce968135Sopenharmony_ci    public:
30ce968135Sopenharmony_ci        using InputAction = std::function<napi_status(napi_env, size_t, napi_value *, napi_value)>;
31ce968135Sopenharmony_ci        using OutputAction = std::function<napi_status(napi_env, napi_value *)>;
32ce968135Sopenharmony_ci        using ExecAction = std::function<void(Context *)>;
33ce968135Sopenharmony_ci        Context(InputAction input, OutputAction output) : input_(std::move(input)), output_(std::move(output)) {};
34ce968135Sopenharmony_ci        virtual ~Context() {};
35ce968135Sopenharmony_ci        void SetAction(InputAction input, OutputAction output = nullptr)
36ce968135Sopenharmony_ci        {
37ce968135Sopenharmony_ci            input_ = input;
38ce968135Sopenharmony_ci            output_ = output;
39ce968135Sopenharmony_ci        }
40ce968135Sopenharmony_ci
41ce968135Sopenharmony_ci        void SetExecution(ExecAction exec)
42ce968135Sopenharmony_ci        {
43ce968135Sopenharmony_ci            exec_ = exec;
44ce968135Sopenharmony_ci        }
45ce968135Sopenharmony_ci
46ce968135Sopenharmony_ci        void SetErrInfo(int32_t errCode, std::string errMsg)
47ce968135Sopenharmony_ci        {
48ce968135Sopenharmony_ci            errCode_ = errCode;
49ce968135Sopenharmony_ci            errMsg_ = errMsg;
50ce968135Sopenharmony_ci        }
51ce968135Sopenharmony_ci
52ce968135Sopenharmony_ci        virtual napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self)
53ce968135Sopenharmony_ci        {
54ce968135Sopenharmony_ci            if (input_ == nullptr) {
55ce968135Sopenharmony_ci                return napi_ok;
56ce968135Sopenharmony_ci            }
57ce968135Sopenharmony_ci            auto ret = input_(env, argc, argv, self);
58ce968135Sopenharmony_ci            input_ = nullptr;
59ce968135Sopenharmony_ci            return ret;
60ce968135Sopenharmony_ci        }
61ce968135Sopenharmony_ci
62ce968135Sopenharmony_ci        virtual napi_status operator()(napi_env env, napi_value *result)
63ce968135Sopenharmony_ci        {
64ce968135Sopenharmony_ci            if (output_ == nullptr) {
65ce968135Sopenharmony_ci                *result = nullptr;
66ce968135Sopenharmony_ci                return napi_ok;
67ce968135Sopenharmony_ci            }
68ce968135Sopenharmony_ci            auto ret = output_(env, result);
69ce968135Sopenharmony_ci            output_ = nullptr;
70ce968135Sopenharmony_ci            return ret;
71ce968135Sopenharmony_ci        }
72ce968135Sopenharmony_ci
73ce968135Sopenharmony_ci        virtual void Exec()
74ce968135Sopenharmony_ci        {
75ce968135Sopenharmony_ci            if (exec_ == nullptr) {
76ce968135Sopenharmony_ci                return;
77ce968135Sopenharmony_ci            }
78ce968135Sopenharmony_ci            exec_(this);
79ce968135Sopenharmony_ci            exec_ = nullptr;
80ce968135Sopenharmony_ci        };
81ce968135Sopenharmony_ci
82ce968135Sopenharmony_ci    protected:
83ce968135Sopenharmony_ci        friend class Call;
84ce968135Sopenharmony_ci        InputAction input_ = nullptr;
85ce968135Sopenharmony_ci        OutputAction output_ = nullptr;
86ce968135Sopenharmony_ci        ExecAction exec_ = nullptr;
87ce968135Sopenharmony_ci        int32_t errCode_ = 0;
88ce968135Sopenharmony_ci        std::string errMsg_;
89ce968135Sopenharmony_ci    };
90ce968135Sopenharmony_ci
91ce968135Sopenharmony_ci    // The default AsyncCallback in the parameters is at the end position.
92ce968135Sopenharmony_ci    static constexpr size_t ASYNC_DEFAULT_POS = -1;
93ce968135Sopenharmony_ci    Call(napi_env env, napi_callback_info info, std::shared_ptr<Context> context, size_t pos = ASYNC_DEFAULT_POS,
94ce968135Sopenharmony_ci        bool needException = true);
95ce968135Sopenharmony_ci    ~Call();
96ce968135Sopenharmony_ci    napi_value AsyncCall(napi_env env, const std::string &resourceName = "AsyncCall");
97ce968135Sopenharmony_ci    napi_value SyncCall(napi_env env);
98ce968135Sopenharmony_ci
99ce968135Sopenharmony_ciprivate:
100ce968135Sopenharmony_ci    enum Arg : int32_t { ARG_ERROR, ARG_DATA, ARG_BUTT };
101ce968135Sopenharmony_ci    struct CallContext {
102ce968135Sopenharmony_ci        std::shared_ptr<Context> ctx = nullptr;
103ce968135Sopenharmony_ci        napi_ref callback = nullptr;
104ce968135Sopenharmony_ci        napi_ref self = nullptr;
105ce968135Sopenharmony_ci        napi_deferred defer = nullptr;
106ce968135Sopenharmony_ci        napi_async_work work = nullptr;
107ce968135Sopenharmony_ci    };
108ce968135Sopenharmony_ci    static void OnExecute(napi_env env, void *data);
109ce968135Sopenharmony_ci    static void OnComplete(napi_env env, napi_status status, void *data);
110ce968135Sopenharmony_ci    static void DeleteContext(napi_env env, CallContext *context);
111ce968135Sopenharmony_ci
112ce968135Sopenharmony_ci    CallContext *context_ = nullptr;
113ce968135Sopenharmony_ci    napi_env env_ = nullptr;
114ce968135Sopenharmony_ci};
115ce968135Sopenharmony_ci} // namespace OHOS::WallpaperNAPI
116ce968135Sopenharmony_ci
117ce968135Sopenharmony_ci#endif // WALLPAPER_CALL_H
118