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
16#include "hiview_file_info.h"
17#include "hiview_napi_adapter.h"
18#include "hiview_napi_util.h"
19#include "hiview_service_agent.h"
20#include "hiview_logger.h"
21#include "napi/native_api.h"
22#include "napi/native_node_api.h"
23#include "string_util.h"
24
25namespace OHOS {
26namespace HiviewDFX {
27DEFINE_LOG_LABEL(0xD002D03, "NAPI_HIVIEW_JS");
28namespace {
29constexpr size_t LOG_TYPE_INDEX = 0;
30constexpr size_t LOG_NAME_INDEX = 1;
31constexpr size_t DEST_DIR_INDEX = 2;
32}
33
34static napi_value List(napi_env env, napi_callback_info info)
35{
36    if (!HiviewNapiUtil::IsSystemAppCall()) {
37        HiviewNapiUtil::ThrowSystemAppPermissionError(env);
38        return nullptr;
39    }
40    constexpr size_t listParamNum = 1;
41    size_t paramNum = listParamNum;
42    napi_value params[listParamNum] = { 0 };
43    napi_value result = nullptr;
44    napi_get_undefined(env, &result);
45    NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, nullptr, nullptr));
46    if (paramNum < listParamNum) {
47        HIVIEW_LOGE("num of params is invalid: %{public}zu", paramNum);
48        return result;
49    }
50    std::string logType;
51    if (!HiviewNapiUtil::ParseStringValue(env, "logType", params[LOG_TYPE_INDEX], logType)) {
52        return result;
53    }
54    std::vector<HiviewFileInfo> fileInfos;
55    int32_t retCode = HiviewServiceAgent::GetInstance().List(logType, fileInfos);
56    HIVIEW_LOGI("retCode: %{public}u.", retCode);
57    if (retCode == 0) {
58        return HiviewNapiUtil::GenerateFileInfoResult(env, fileInfos);
59    } else {
60        HiviewNapiUtil::ThrowErrorByCode(env, retCode);
61        return result;
62    }
63}
64
65static napi_value CopyOrMoveFile(napi_env env, napi_callback_info info, bool isMove)
66{
67    if (isMove) {
68        HIVIEW_LOGI("call move");
69    } else {
70        HIVIEW_LOGI("call copy");
71    }
72    constexpr size_t maxParamNum = 4;
73    constexpr size_t paramNumWithoutCallback = 3;
74    size_t paramNum = maxParamNum;
75    napi_value params[maxParamNum] = { 0 };
76    NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, nullptr, nullptr));
77    napi_value result = nullptr;
78    napi_get_undefined(env, &result);
79    if (paramNum < paramNumWithoutCallback) {
80        HIVIEW_LOGE("num of params is invalid %{public}zu.", paramNum);
81        return result;
82    }
83    std::string logType;
84    std::string logName;
85    std::string destDir;
86    if (!HiviewNapiUtil::ParseStringValue(env, "logType", params[LOG_TYPE_INDEX], logType)
87        || !HiviewNapiUtil::ParseStringValue(env, "logName", params[LOG_NAME_INDEX], logName)
88        || !HiviewNapiUtil::ParseStringValue(env, "dest", params[DEST_DIR_INDEX], destDir)) {
89        return result;
90    }
91    HIVIEW_LOGI("type:%{public}s, name:%{public}s, dir: %{public}s",
92        logType.c_str(), StringUtil::HideSnInfo(logName).c_str(), destDir.c_str());
93    if (!HiviewNapiUtil::CheckDirPath(destDir)) {
94        HIVIEW_LOGE("dest param is invalid: %{public}s", destDir.c_str());
95        HiviewNapiUtil::ThrowParamContentError(env, "dest");
96        return result;
97    }
98    HiviewFileParams* hiviewFileParams = new(std::nothrow) HiviewFileParams(logType, logName, destDir);
99    if (hiviewFileParams == nullptr) {
100        HIVIEW_LOGE("failed to allocate memory");
101        return result;
102    } else if (paramNum == maxParamNum) {
103        if (!HiviewNapiUtil::IsMatchType(env, params[paramNumWithoutCallback], napi_function)) {
104            HIVIEW_LOGE("no valid function param");
105            HiviewNapiUtil::ThrowParamTypeError(env, "callback", "function");
106            delete hiviewFileParams;
107            return result;
108        }
109        napi_create_reference(env, params[paramNumWithoutCallback], 1, &hiviewFileParams->callback);
110    } else {
111        napi_create_promise(env, &hiviewFileParams->deferred, &result);
112    }
113    isMove ? HiviewNapiAdapter::Move(env, hiviewFileParams) : HiviewNapiAdapter::Copy(env, hiviewFileParams);
114    return result;
115}
116
117static napi_value Copy(napi_env env, napi_callback_info info)
118{
119    if (!HiviewNapiUtil::IsSystemAppCall()) {
120        HiviewNapiUtil::ThrowSystemAppPermissionError(env);
121        return nullptr;
122    }
123    return CopyOrMoveFile(env, info, false);
124}
125
126static napi_value Move(napi_env env, napi_callback_info info)
127{
128    if (!HiviewNapiUtil::IsSystemAppCall()) {
129        HiviewNapiUtil::ThrowSystemAppPermissionError(env);
130        return nullptr;
131    }
132    return CopyOrMoveFile(env, info, true);
133}
134
135static napi_value Remove(napi_env env, napi_callback_info info)
136{
137    if (!HiviewNapiUtil::IsSystemAppCall()) {
138        HiviewNapiUtil::ThrowSystemAppPermissionError(env);
139        return nullptr;
140    }
141    constexpr size_t removeParamNum = 2;
142    size_t paramNum = removeParamNum;
143    napi_value params[removeParamNum] = { 0 };
144    napi_value result = nullptr;
145    napi_get_undefined(env, &result);
146    NAPI_CALL(env, napi_get_cb_info(env, info, &paramNum, params, nullptr, nullptr));
147    if (paramNum < removeParamNum) {
148        HIVIEW_LOGE("num of params is invalid: %{public}zu", paramNum);
149        return result;
150    }
151    std::string logType;
152    std::string logName;
153    if (!HiviewNapiUtil::ParseStringValue(env, "logType", params[LOG_TYPE_INDEX], logType)
154        || !HiviewNapiUtil::ParseStringValue(env, "logName", params[LOG_NAME_INDEX], logName)) {
155        return result;
156    }
157    HIVIEW_LOGI("type: %{public}s, name: %{public}s", logType.c_str(), StringUtil::HideSnInfo(logName).c_str());
158    int32_t retCode = HiviewServiceAgent::GetInstance().Remove(logType, logName);
159    if (retCode != 0) {
160        HIVIEW_LOGI("retCode: %{public}u.", retCode);
161        HiviewNapiUtil::ThrowErrorByCode(env, retCode);
162    }
163    return result;
164}
165
166EXTERN_C_START
167static napi_value Init(napi_env env, napi_value exports)
168{
169    napi_property_descriptor desc[] = {
170        DECLARE_NAPI_FUNCTION("list", List),
171        DECLARE_NAPI_FUNCTION("copy", Copy),
172        DECLARE_NAPI_FUNCTION("move", Move),
173        DECLARE_NAPI_FUNCTION("remove", Remove)
174    };
175    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
176    return exports;
177}
178EXTERN_C_END
179
180static napi_module _module = {
181    .nm_version = 1,
182    .nm_flags = 0,
183    .nm_filename = nullptr,
184    .nm_register_func = Init,
185    .nm_modname = "logLibrary",
186    .nm_priv = ((void *) 0),
187    .reserved = {0}
188};
189
190extern "C" __attribute__((constructor)) void RegisterModule(void)
191{
192    napi_module_register(&_module);
193}
194} // namespace HiviewDFX
195} // namespace OHOS