1b8a72a62Sopenharmony_ci/*
2b8a72a62Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3b8a72a62Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b8a72a62Sopenharmony_ci * you may not use this file except in compliance with the License.
5b8a72a62Sopenharmony_ci * You may obtain a copy of the License at
6b8a72a62Sopenharmony_ci *
7b8a72a62Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b8a72a62Sopenharmony_ci *
9b8a72a62Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b8a72a62Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b8a72a62Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b8a72a62Sopenharmony_ci * See the License for the specific language governing permissions and
13b8a72a62Sopenharmony_ci * limitations under the License.
14b8a72a62Sopenharmony_ci */
15b8a72a62Sopenharmony_ci
16b8a72a62Sopenharmony_ci#include "packager.h"
17b8a72a62Sopenharmony_ci
18b8a72a62Sopenharmony_ci#include <filesystem>
19b8a72a62Sopenharmony_ci#include <fstream>
20b8a72a62Sopenharmony_ci#include <random>
21b8a72a62Sopenharmony_ci#include <sstream>
22b8a72a62Sopenharmony_ci#include <string>
23b8a72a62Sopenharmony_ci#include <unordered_set>
24b8a72a62Sopenharmony_ci
25b8a72a62Sopenharmony_ci#include "json/json_utils.h"
26b8a72a62Sopenharmony_ci#include "log.h"
27b8a72a62Sopenharmony_ci#include "utils.h"
28b8a72a62Sopenharmony_ci#include "zip_utils.h"
29b8a72a62Sopenharmony_ci
30b8a72a62Sopenharmony_cinamespace OHOS {
31b8a72a62Sopenharmony_cinamespace AppPackingTool {
32b8a72a62Sopenharmony_cinamespace {
33b8a72a62Sopenharmony_ciconst std::string EN_US_UTF_8 = "en_US.UTF-8";
34b8a72a62Sopenharmony_ci}
35b8a72a62Sopenharmony_ci
36b8a72a62Sopenharmony_ciPackager::Packager(const std::map<std::string, std::string> &parameterMap, std::string &resultReceiver)
37b8a72a62Sopenharmony_ci    : parameterMap_(parameterMap), resultReceiver_(resultReceiver)
38b8a72a62Sopenharmony_ci{}
39b8a72a62Sopenharmony_ci
40b8a72a62Sopenharmony_ciPackager::~Packager()
41b8a72a62Sopenharmony_ci{}
42b8a72a62Sopenharmony_ci
43b8a72a62Sopenharmony_cistd::string Packager::MakePackage()
44b8a72a62Sopenharmony_ci{
45b8a72a62Sopenharmony_ci    if (InitAllowedParam() != ERR_OK) {
46b8a72a62Sopenharmony_ci        LOGE("InitAllowedParam err");
47b8a72a62Sopenharmony_ci        return "";
48b8a72a62Sopenharmony_ci    }
49b8a72a62Sopenharmony_ci
50b8a72a62Sopenharmony_ci    if (PreProcess() != ERR_OK) {
51b8a72a62Sopenharmony_ci        LOGE("PreProcess err");
52b8a72a62Sopenharmony_ci        return "";
53b8a72a62Sopenharmony_ci    }
54b8a72a62Sopenharmony_ci
55b8a72a62Sopenharmony_ci    if (Process() != ERR_OK) {
56b8a72a62Sopenharmony_ci        LOGE("Process err");
57b8a72a62Sopenharmony_ci        return "";
58b8a72a62Sopenharmony_ci    }
59b8a72a62Sopenharmony_ci
60b8a72a62Sopenharmony_ci    if (PostProcess() != ERR_OK) {
61b8a72a62Sopenharmony_ci        LOGE("PostProcess err");
62b8a72a62Sopenharmony_ci        return "";
63b8a72a62Sopenharmony_ci    }
64b8a72a62Sopenharmony_ci    return "OHOS::ERR_OK";
65b8a72a62Sopenharmony_ci}
66b8a72a62Sopenharmony_ci
67b8a72a62Sopenharmony_ciint32_t Packager::PreProcess()
68b8a72a62Sopenharmony_ci{
69b8a72a62Sopenharmony_ci    resultReceiver_.append("do PreProcess\n");
70b8a72a62Sopenharmony_ci    return ERR_OK;
71b8a72a62Sopenharmony_ci}
72b8a72a62Sopenharmony_ci
73b8a72a62Sopenharmony_ciint32_t Packager::Process()
74b8a72a62Sopenharmony_ci{
75b8a72a62Sopenharmony_ci    resultReceiver_.append("do Process\n");
76b8a72a62Sopenharmony_ci    return ERR_OK;
77b8a72a62Sopenharmony_ci}
78b8a72a62Sopenharmony_ci
79b8a72a62Sopenharmony_ciint32_t Packager::PostProcess()
80b8a72a62Sopenharmony_ci{
81b8a72a62Sopenharmony_ci    resultReceiver_.append("do PostProcess\n");
82b8a72a62Sopenharmony_ci    return ERR_OK;
83b8a72a62Sopenharmony_ci}
84b8a72a62Sopenharmony_ci
85b8a72a62Sopenharmony_cibool Packager::CheckForceFlag()
86b8a72a62Sopenharmony_ci{
87b8a72a62Sopenharmony_ci    auto it = parameterMap_.find(Constants::PARAM_FORCE);
88b8a72a62Sopenharmony_ci    if (it != parameterMap_.end() && it->second != "false" && it->second != "true") {
89b8a72a62Sopenharmony_ci        LOGE("Packager::commandVerify forceRewrite is invalid.");
90b8a72a62Sopenharmony_ci        return false;
91b8a72a62Sopenharmony_ci    }
92b8a72a62Sopenharmony_ci    return true;
93b8a72a62Sopenharmony_ci}
94b8a72a62Sopenharmony_ci
95b8a72a62Sopenharmony_cibool Packager::IsPathValid(const std::string &path, const bool &isFile, const std::string suffix)
96b8a72a62Sopenharmony_ci{
97b8a72a62Sopenharmony_ci    if (isFile && fs::is_regular_file(path)) {
98b8a72a62Sopenharmony_ci        std::string name = fs::path(path).filename();
99b8a72a62Sopenharmony_ci        std::locale englishLocale(EN_US_UTF_8);
100b8a72a62Sopenharmony_ci        std::transform(name.begin(), name.end(), name.begin(),
101b8a72a62Sopenharmony_ci                       [&englishLocale](unsigned char c) { return std::tolower(c); });
102b8a72a62Sopenharmony_ci        if (Utils::EndsWith(name, suffix)) {
103b8a72a62Sopenharmony_ci            return true;
104b8a72a62Sopenharmony_ci        }
105b8a72a62Sopenharmony_ci    }
106b8a72a62Sopenharmony_ci    return (!isFile) && fs::is_directory(path);
107b8a72a62Sopenharmony_ci}
108b8a72a62Sopenharmony_ci
109b8a72a62Sopenharmony_cibool Packager::SplitDirList(const std::string &dirList, std::list<std::string> &fileList)
110b8a72a62Sopenharmony_ci{
111b8a72a62Sopenharmony_ci    std::list<std::string> pathList;
112b8a72a62Sopenharmony_ci    RemoveDuplicatePath(dirList, pathList);
113b8a72a62Sopenharmony_ci    for (const std::string &pathItem : pathList) {
114b8a72a62Sopenharmony_ci        std::string formattedPathItem;
115b8a72a62Sopenharmony_ci        if (!Utils::GetFormattedPath(pathItem, formattedPathItem)) {
116b8a72a62Sopenharmony_ci            LOGE("GetFormattedPath failed for %s", pathItem.c_str());
117b8a72a62Sopenharmony_ci            return false;
118b8a72a62Sopenharmony_ci        };
119b8a72a62Sopenharmony_ci        if (!IsPathValid(formattedPathItem, false)) {
120b8a72a62Sopenharmony_ci            return false;
121b8a72a62Sopenharmony_ci        }
122b8a72a62Sopenharmony_ci        fileList.push_back(formattedPathItem);
123b8a72a62Sopenharmony_ci    }
124b8a72a62Sopenharmony_ci    return true;
125b8a72a62Sopenharmony_ci}
126b8a72a62Sopenharmony_ci
127b8a72a62Sopenharmony_civoid Packager::RemoveDuplicatePath(const std::string &path, std::list<std::string> &pathList)
128b8a72a62Sopenharmony_ci{
129b8a72a62Sopenharmony_ci    std::string pathItem;
130b8a72a62Sopenharmony_ci    std::istringstream pathStream(path);
131b8a72a62Sopenharmony_ci    while (std::getline(pathStream, pathItem, Constants::COMMA_SPLIT)) {
132b8a72a62Sopenharmony_ci        pathList.push_back(pathItem);
133b8a72a62Sopenharmony_ci    }
134b8a72a62Sopenharmony_ci    std::unordered_set<std::string> uniqueTokens(pathList.begin(), pathList.end());
135b8a72a62Sopenharmony_ci    pathList.assign(uniqueTokens.begin(), uniqueTokens.end());
136b8a72a62Sopenharmony_ci}
137b8a72a62Sopenharmony_ci
138b8a72a62Sopenharmony_cibool Packager::CompatibleProcess(const std::string &inputPath, std::list<std::string> &fileList,
139b8a72a62Sopenharmony_ci    const std::string &suffix)
140b8a72a62Sopenharmony_ci{
141b8a72a62Sopenharmony_ci    if (IsPathValid(inputPath, false)) {
142b8a72a62Sopenharmony_ci        for (const auto& fileItem : fs::recursive_directory_iterator(inputPath)) {
143b8a72a62Sopenharmony_ci            std::string name = fileItem.path().filename();
144b8a72a62Sopenharmony_ci            std::locale englishLocale(EN_US_UTF_8);
145b8a72a62Sopenharmony_ci            std::transform(name.begin(), name.end(), name.begin(),
146b8a72a62Sopenharmony_ci                 [&englishLocale](unsigned char c) { return std::tolower(c); });
147b8a72a62Sopenharmony_ci            if (Utils::EndsWith(name, suffix)) {
148b8a72a62Sopenharmony_ci                fileList.push_back(fileItem.path().string());
149b8a72a62Sopenharmony_ci            }
150b8a72a62Sopenharmony_ci        }
151b8a72a62Sopenharmony_ci        return true;
152b8a72a62Sopenharmony_ci    } else {
153b8a72a62Sopenharmony_ci        std::string formattedPathItem;
154b8a72a62Sopenharmony_ci        std::list<std::string> pathList;
155b8a72a62Sopenharmony_ci        RemoveDuplicatePath(inputPath, pathList);
156b8a72a62Sopenharmony_ci        for (std::string pathItem : pathList) {
157b8a72a62Sopenharmony_ci            if (!Utils::GetFormattedPath(pathItem, formattedPathItem)) {
158b8a72a62Sopenharmony_ci                LOGE("GetFormattedPath failed for %s", pathItem.c_str());
159b8a72a62Sopenharmony_ci                return false;
160b8a72a62Sopenharmony_ci            };
161b8a72a62Sopenharmony_ci            if (!IsPathValid(formattedPathItem, true, suffix)) {
162b8a72a62Sopenharmony_ci                return false;
163b8a72a62Sopenharmony_ci            }
164b8a72a62Sopenharmony_ci            fileList.push_back(formattedPathItem);
165b8a72a62Sopenharmony_ci        }
166b8a72a62Sopenharmony_ci        return true;
167b8a72a62Sopenharmony_ci    }
168b8a72a62Sopenharmony_ci}
169b8a72a62Sopenharmony_ci
170b8a72a62Sopenharmony_cibool Packager::CompatibleProcess(const std::string &inputPath, std::list<std::string> &fileList,
171b8a72a62Sopenharmony_ci    const std::string &suffix, const std::string &extraSuffix)
172b8a72a62Sopenharmony_ci{
173b8a72a62Sopenharmony_ci    if (IsPathValid(inputPath, false)) {
174b8a72a62Sopenharmony_ci        for (const auto& fileItem : fs::recursive_directory_iterator(inputPath)) {
175b8a72a62Sopenharmony_ci            std::string name = fileItem.path().filename();
176b8a72a62Sopenharmony_ci            std::locale englishLocale(EN_US_UTF_8);
177b8a72a62Sopenharmony_ci            std::transform(name.begin(), name.end(), name.begin(),
178b8a72a62Sopenharmony_ci                 [&englishLocale](unsigned char c) { return std::tolower(c); });
179b8a72a62Sopenharmony_ci            if (Utils::EndsWith(name, suffix) || Utils::EndsWith(name, extraSuffix)) {
180b8a72a62Sopenharmony_ci                fileList.push_back(fileItem.path().string());
181b8a72a62Sopenharmony_ci            }
182b8a72a62Sopenharmony_ci        }
183b8a72a62Sopenharmony_ci        return true;
184b8a72a62Sopenharmony_ci    } else {
185b8a72a62Sopenharmony_ci        std::string formattedPathItem;
186b8a72a62Sopenharmony_ci        std::list<std::string> pathList;
187b8a72a62Sopenharmony_ci        RemoveDuplicatePath(inputPath, pathList);
188b8a72a62Sopenharmony_ci        for (std::string pathItem : pathList) {
189b8a72a62Sopenharmony_ci            if (!Utils::GetFormattedPath(pathItem, formattedPathItem)) {
190b8a72a62Sopenharmony_ci                LOGE("GetFormattedPath failed for %s", pathItem.c_str());
191b8a72a62Sopenharmony_ci                return false;
192b8a72a62Sopenharmony_ci            };
193b8a72a62Sopenharmony_ci            if (!IsPathValid(formattedPathItem, true, suffix) &&
194b8a72a62Sopenharmony_ci                !IsPathValid(formattedPathItem, true, extraSuffix)) {
195b8a72a62Sopenharmony_ci                return false;
196b8a72a62Sopenharmony_ci            }
197b8a72a62Sopenharmony_ci            fileList.push_back(formattedPathItem);
198b8a72a62Sopenharmony_ci        }
199b8a72a62Sopenharmony_ci        return true;
200b8a72a62Sopenharmony_ci    }
201b8a72a62Sopenharmony_ci}
202b8a72a62Sopenharmony_ci
203b8a72a62Sopenharmony_cibool Packager::IsOutPathValid(const std::string &outPath, const std::string &forceRewrite, const std::string &suffix)
204b8a72a62Sopenharmony_ci{
205b8a72a62Sopenharmony_ci    fs::path filePath(outPath);
206b8a72a62Sopenharmony_ci
207b8a72a62Sopenharmony_ci    if ("false" == forceRewrite && fs::exists(filePath)) {
208b8a72a62Sopenharmony_ci        LOGE("Packager::isOutPathValid out file already existed.");
209b8a72a62Sopenharmony_ci        return false;
210b8a72a62Sopenharmony_ci    }
211b8a72a62Sopenharmony_ci
212b8a72a62Sopenharmony_ci    if (suffix == Constants::HAP_SUFFIX) {
213b8a72a62Sopenharmony_ci        if (!Utils::EndsWith(filePath.filename().string(), Constants::HAP_SUFFIX)) {
214b8a72a62Sopenharmony_ci            LOGE("Packager::isOutPathValid out-path must end with .hap.");
215b8a72a62Sopenharmony_ci            return false;
216b8a72a62Sopenharmony_ci        } else {
217b8a72a62Sopenharmony_ci            return true;
218b8a72a62Sopenharmony_ci        }
219b8a72a62Sopenharmony_ci    } else if (suffix == Constants::HAR_SUFFIX) {
220b8a72a62Sopenharmony_ci        if (!Utils::EndsWith(filePath.filename().string(), Constants::HAR_SUFFIX)) {
221b8a72a62Sopenharmony_ci            LOGE("Packager::isOutPathValid out-path must end with .har.");
222b8a72a62Sopenharmony_ci            return false;
223b8a72a62Sopenharmony_ci        } else {
224b8a72a62Sopenharmony_ci            return true;
225b8a72a62Sopenharmony_ci        }
226b8a72a62Sopenharmony_ci    } else if (suffix == Constants::APP_SUFFIX) {
227b8a72a62Sopenharmony_ci        if (!Utils::EndsWith(filePath.filename().string(), Constants::APP_SUFFIX)) {
228b8a72a62Sopenharmony_ci            LOGE("Packager::isOutPathValid out-path must end with .app.");
229b8a72a62Sopenharmony_ci            return false;
230b8a72a62Sopenharmony_ci        } else {
231b8a72a62Sopenharmony_ci            return true;
232b8a72a62Sopenharmony_ci        }
233b8a72a62Sopenharmony_ci    } else if (suffix == Constants::RES_SUFFIX) {
234b8a72a62Sopenharmony_ci        if (!Utils::EndsWith(filePath.filename().string(), Constants::RES_SUFFIX)) {
235b8a72a62Sopenharmony_ci            LOGE("Packager::isOutPathValid out-path must end with .res.");
236b8a72a62Sopenharmony_ci            return false;
237b8a72a62Sopenharmony_ci        } else {
238b8a72a62Sopenharmony_ci            return true;
239b8a72a62Sopenharmony_ci        }
240b8a72a62Sopenharmony_ci    } else if (suffix == Constants::HSP_SUFFIX) {
241b8a72a62Sopenharmony_ci        if (!Utils::EndsWith(filePath.filename().string(), Constants::HSP_SUFFIX)) {
242b8a72a62Sopenharmony_ci            LOGE("Packager::isOutPathValid out-path must end with .hsp.");
243b8a72a62Sopenharmony_ci            return false;
244b8a72a62Sopenharmony_ci        } else {
245b8a72a62Sopenharmony_ci            return true;
246b8a72a62Sopenharmony_ci        }
247b8a72a62Sopenharmony_ci    }
248b8a72a62Sopenharmony_ci    return false;
249b8a72a62Sopenharmony_ci}
250b8a72a62Sopenharmony_ci
251b8a72a62Sopenharmony_cibool Packager::SetGenerateBuildHash(std::string &jsonPath, bool &generateBuildHash, bool &buildHashFinish)
252b8a72a62Sopenharmony_ci{
253b8a72a62Sopenharmony_ci    if (!fs::exists(jsonPath)) {
254b8a72a62Sopenharmony_ci        LOGE("Packager::setGenerateBuildHash failed for json file not exist");
255b8a72a62Sopenharmony_ci        return false;
256b8a72a62Sopenharmony_ci    }
257b8a72a62Sopenharmony_ci    ModuleJson moduleJson;
258b8a72a62Sopenharmony_ci    moduleJson.ParseFromFile(jsonPath);
259b8a72a62Sopenharmony_ci
260b8a72a62Sopenharmony_ci    if (buildHashFinish || !moduleJson.GetGenerateBuildHash(generateBuildHash)) {
261b8a72a62Sopenharmony_ci        return true;
262b8a72a62Sopenharmony_ci    }
263b8a72a62Sopenharmony_ci
264b8a72a62Sopenharmony_ci    if (!CopyFileToTempDir(jsonPath)) {
265b8a72a62Sopenharmony_ci        return false;
266b8a72a62Sopenharmony_ci    }
267b8a72a62Sopenharmony_ci
268b8a72a62Sopenharmony_ci    if (!fs::exists(jsonPath)) {
269b8a72a62Sopenharmony_ci        LOGE("Packager::setGenerateBuildHash failed for json file not exist");
270b8a72a62Sopenharmony_ci        return false;
271b8a72a62Sopenharmony_ci    }
272b8a72a62Sopenharmony_ci
273b8a72a62Sopenharmony_ci    ModuleJson moduleJsonTemp;
274b8a72a62Sopenharmony_ci    moduleJsonTemp.ParseFromFile(jsonPath);
275b8a72a62Sopenharmony_ci    if (!moduleJsonTemp.GetGenerateBuildHash(generateBuildHash)) {
276b8a72a62Sopenharmony_ci        LOGE("ModuleJson::GetGenerateBuildHash failed");
277b8a72a62Sopenharmony_ci        return false;
278b8a72a62Sopenharmony_ci    }
279b8a72a62Sopenharmony_ci
280b8a72a62Sopenharmony_ci    if (!moduleJsonTemp.RemoveGenerateBuildHash()) {
281b8a72a62Sopenharmony_ci        LOGE("ModuleJson::RemoveGenerateBuildHash failed");
282b8a72a62Sopenharmony_ci        return false;
283b8a72a62Sopenharmony_ci    }
284b8a72a62Sopenharmony_ci
285b8a72a62Sopenharmony_ci    std::string prettyJsonString = moduleJsonTemp.ToString();
286b8a72a62Sopenharmony_ci    if (prettyJsonString.empty()) {
287b8a72a62Sopenharmony_ci        LOGE("ModuleJson::ToString failed");
288b8a72a62Sopenharmony_ci        return false;
289b8a72a62Sopenharmony_ci    }
290b8a72a62Sopenharmony_ci
291b8a72a62Sopenharmony_ci    std::string realJsonPath;
292b8a72a62Sopenharmony_ci    if (!Utils::GetRealPath(jsonPath, realJsonPath)) {
293b8a72a62Sopenharmony_ci        LOGE("get real json Path failed! jsonPath=%s", jsonPath.c_str());
294b8a72a62Sopenharmony_ci        return false;
295b8a72a62Sopenharmony_ci    }
296b8a72a62Sopenharmony_ci    std::ofstream outFile(realJsonPath);
297b8a72a62Sopenharmony_ci    if (outFile.is_open()) {
298b8a72a62Sopenharmony_ci        outFile << prettyJsonString.c_str();
299b8a72a62Sopenharmony_ci        outFile.close();
300b8a72a62Sopenharmony_ci    } else {
301b8a72a62Sopenharmony_ci        LOGE("Failed to open file for writing");
302b8a72a62Sopenharmony_ci        return false;
303b8a72a62Sopenharmony_ci    }
304b8a72a62Sopenharmony_ci    return true;
305b8a72a62Sopenharmony_ci}
306b8a72a62Sopenharmony_ci
307b8a72a62Sopenharmony_cibool Packager::CopyFileToTempDir(std::string &jsonPath)
308b8a72a62Sopenharmony_ci{
309b8a72a62Sopenharmony_ci    if (!fs::exists(jsonPath)) {
310b8a72a62Sopenharmony_ci        LOGE("Packager::copyFileToTempDir failed for json file not found.");
311b8a72a62Sopenharmony_ci        return false;
312b8a72a62Sopenharmony_ci    }
313b8a72a62Sopenharmony_ci    fs::path oldFileParent = fs::path(jsonPath).parent_path();
314b8a72a62Sopenharmony_ci    std::string tempDir = Constants::COMPRESSOR_TEMP_DIR + fs::path::preferred_separator + Utils::GenerateUUID();
315b8a72a62Sopenharmony_ci    fs::path tempDirFs(tempDir);
316b8a72a62Sopenharmony_ci    tempDir = oldFileParent.string() + fs::path::preferred_separator + tempDirFs.string();
317b8a72a62Sopenharmony_ci    fs::create_directories(tempDir);
318b8a72a62Sopenharmony_ci    fs::path fileName = JsonUtils::IsModuleJson(jsonPath) ? Constants::MODULE_JSON : Constants::CONFIG_JSON;
319b8a72a62Sopenharmony_ci    std::string tempPath = tempDir + fs::path::preferred_separator + fileName.string();
320b8a72a62Sopenharmony_ci    if (!Utils::CopyFile(jsonPath, tempPath)) {
321b8a72a62Sopenharmony_ci        return false;
322b8a72a62Sopenharmony_ci    }
323b8a72a62Sopenharmony_ci    jsonPath = tempPath;
324b8a72a62Sopenharmony_ci    return true;
325b8a72a62Sopenharmony_ci}
326b8a72a62Sopenharmony_ci
327b8a72a62Sopenharmony_cibool Packager::BuildHash(bool &buildHashFinish, const bool &generateBuildHash,
328b8a72a62Sopenharmony_ci    const std::map<std::string, std::string> &parameterMap, const std::string &jsonPath)
329b8a72a62Sopenharmony_ci{
330b8a72a62Sopenharmony_ci    if (buildHashFinish || !generateBuildHash) {
331b8a72a62Sopenharmony_ci        return true;
332b8a72a62Sopenharmony_ci    }
333b8a72a62Sopenharmony_ci    std::map<std::string, std::string>::const_iterator it = parameterMap.find(Constants::PARAM_OUT_PATH);
334b8a72a62Sopenharmony_ci    if (it == parameterMap.end()) {
335b8a72a62Sopenharmony_ci        LOGE("out-path not found");
336b8a72a62Sopenharmony_ci        return false;
337b8a72a62Sopenharmony_ci    }
338b8a72a62Sopenharmony_ci    std::string filePath = it->second;
339b8a72a62Sopenharmony_ci    std::string hash = Utils::GetSha256File(filePath);
340b8a72a62Sopenharmony_ci    return PutBuildHash(jsonPath, hash, buildHashFinish);
341b8a72a62Sopenharmony_ci}
342b8a72a62Sopenharmony_ci
343b8a72a62Sopenharmony_cibool Packager::PutBuildHash(const std::string &jsonPath, const std::string &hash, bool &buildHashFinish)
344b8a72a62Sopenharmony_ci{
345b8a72a62Sopenharmony_ci    if (buildHashFinish) {
346b8a72a62Sopenharmony_ci        return true;
347b8a72a62Sopenharmony_ci    }
348b8a72a62Sopenharmony_ci
349b8a72a62Sopenharmony_ci    ModuleJson moduleJson;
350b8a72a62Sopenharmony_ci    moduleJson.ParseFromFile(jsonPath);
351b8a72a62Sopenharmony_ci    moduleJson.SetBuildHash(hash);
352b8a72a62Sopenharmony_ci    std::string prettyJsonString = moduleJson.ToString();
353b8a72a62Sopenharmony_ci    if (prettyJsonString.empty()) {
354b8a72a62Sopenharmony_ci        LOGE("ModuleJson::ToString failed");
355b8a72a62Sopenharmony_ci        return false;
356b8a72a62Sopenharmony_ci    }
357b8a72a62Sopenharmony_ci
358b8a72a62Sopenharmony_ci    std::string realJsonPath;
359b8a72a62Sopenharmony_ci    if (!Utils::GetRealPath(jsonPath, realJsonPath)) {
360b8a72a62Sopenharmony_ci        LOGE("get real json path failed! jsonFile=%s", jsonPath.c_str());
361b8a72a62Sopenharmony_ci        return false;
362b8a72a62Sopenharmony_ci    }
363b8a72a62Sopenharmony_ci    std::ofstream outFile(realJsonPath);
364b8a72a62Sopenharmony_ci    if (outFile.is_open()) {
365b8a72a62Sopenharmony_ci        outFile << prettyJsonString.c_str();
366b8a72a62Sopenharmony_ci        outFile.close();
367b8a72a62Sopenharmony_ci    } else {
368b8a72a62Sopenharmony_ci        LOGE("Failed to open file for writing");
369b8a72a62Sopenharmony_ci        return false;
370b8a72a62Sopenharmony_ci    }
371b8a72a62Sopenharmony_ci
372b8a72a62Sopenharmony_ci    buildHashFinish = true;
373b8a72a62Sopenharmony_ci    return true;
374b8a72a62Sopenharmony_ci}
375b8a72a62Sopenharmony_ci
376b8a72a62Sopenharmony_cibool Packager::IsModuleHap(const std::string& hapPath)
377b8a72a62Sopenharmony_ci{
378b8a72a62Sopenharmony_ci    if (!Utils::EndsWith(hapPath, Constants::HAP_SUFFIX)) {
379b8a72a62Sopenharmony_ci        return false;
380b8a72a62Sopenharmony_ci    }
381b8a72a62Sopenharmony_ci    if (!ZipUtils::IsFileExistsInZip(hapPath, Constants::MODULE_JSON)) {
382b8a72a62Sopenharmony_ci        return false;
383b8a72a62Sopenharmony_ci    }
384b8a72a62Sopenharmony_ci    return true;
385b8a72a62Sopenharmony_ci}
386b8a72a62Sopenharmony_ci
387b8a72a62Sopenharmony_civoid Packager::CompressPackinfoIntoHap(const std::string& hapPathItem, const std::string& unzipPathString,
388b8a72a62Sopenharmony_ci    const std::string& outPathString, const std::string& packInfoPath)
389b8a72a62Sopenharmony_ci{
390b8a72a62Sopenharmony_ci    if (!fs::exists(fs::path(unzipPathString))) {
391b8a72a62Sopenharmony_ci        fs::create_directory(fs::path(unzipPathString));
392b8a72a62Sopenharmony_ci    }
393b8a72a62Sopenharmony_ci    ZipUtils::Unzip(hapPathItem, unzipPathString);
394b8a72a62Sopenharmony_ci    for (const auto& entry : fs::directory_iterator(unzipPathString)) {
395b8a72a62Sopenharmony_ci        if (entry.path().filename() == Constants::PACK_INFO) {
396b8a72a62Sopenharmony_ci            fs::remove(entry.path());
397b8a72a62Sopenharmony_ci        }
398b8a72a62Sopenharmony_ci    }
399b8a72a62Sopenharmony_ci
400b8a72a62Sopenharmony_ci    std::string realPackInfoPath;
401b8a72a62Sopenharmony_ci    if (!Utils::GetRealPath(packInfoPath, realPackInfoPath)) {
402b8a72a62Sopenharmony_ci        LOGE("get real pack info path failed! packInfoPath=%s", packInfoPath.c_str());
403b8a72a62Sopenharmony_ci        return;
404b8a72a62Sopenharmony_ci    }
405b8a72a62Sopenharmony_ci    std::string destFilePath = unzipPathString + fs::path::preferred_separator + Constants::PACK_INFO;
406b8a72a62Sopenharmony_ci    std::string realDestFilePath;
407b8a72a62Sopenharmony_ci    if (!Utils::GetRealPathOfNoneExistFile(destFilePath, realDestFilePath)) {
408b8a72a62Sopenharmony_ci        LOGE("get real dest file path failed! destFilePath=%s", destFilePath.c_str());
409b8a72a62Sopenharmony_ci        return;
410b8a72a62Sopenharmony_ci    }
411b8a72a62Sopenharmony_ci    std::ifstream packInfoFile(realPackInfoPath, std::ios::binary);
412b8a72a62Sopenharmony_ci    std::ofstream destFile(realDestFilePath, std::ios::binary | std::ios::trunc);
413b8a72a62Sopenharmony_ci    destFile << packInfoFile.rdbuf();
414b8a72a62Sopenharmony_ci    destFile.close();
415b8a72a62Sopenharmony_ci    packInfoFile.close();
416b8a72a62Sopenharmony_ci    ZipUtils::Zip(unzipPathString, outPathString);
417b8a72a62Sopenharmony_ci    if (fs::exists(fs::path(unzipPathString))) {
418b8a72a62Sopenharmony_ci        fs::remove_all(fs::path(unzipPathString));
419b8a72a62Sopenharmony_ci    }
420b8a72a62Sopenharmony_ci}
421b8a72a62Sopenharmony_ci
422b8a72a62Sopenharmony_cibool Packager::IsOutDirectoryValid()
423b8a72a62Sopenharmony_ci{
424b8a72a62Sopenharmony_ci    auto it = parameterMap_.find(Constants::PARAM_OUT_PATH);
425b8a72a62Sopenharmony_ci    if (it == parameterMap_.end()) {
426b8a72a62Sopenharmony_ci        LOGE("Validate out-path is empty");
427b8a72a62Sopenharmony_ci        return false;
428b8a72a62Sopenharmony_ci    } else if (!Utils::IsDirectory(it->second)) {
429b8a72a62Sopenharmony_ci        LOGE("Validate out-path is not a directory.");
430b8a72a62Sopenharmony_ci        return false;
431b8a72a62Sopenharmony_ci    }
432b8a72a62Sopenharmony_ci    return true;
433b8a72a62Sopenharmony_ci}
434b8a72a62Sopenharmony_ci} // namespace AppPackingTool
435b8a72a62Sopenharmony_ci} // namespace OHOS