1/*
2 * Copyright (c) 2024 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 <hash/hash.h>
17#include <fstream>
18#include <iostream>
19#include <sstream>
20
21#include "util/options.h"
22#include "util/common.h"
23#include "util/logger.h"
24
25namespace OHOS {
26namespace Idl {
27bool Hash::GenHashKey()
28{
29    FileDetailMap fileDetails;
30    if (!Preprocessor::UnitPreprocess(fileDetails)) {
31        return false;
32    }
33
34    std::string filePath = Options::GetInstance().GetOutPutFile();
35    return filePath.empty() ? FormatStdout(fileDetails) : FormatFile(fileDetails, filePath);
36}
37
38bool Hash::FormatStdout(const FileDetailMap &fileDetails)
39{
40    std::vector<std::string> hashInfos = Hash::GetHashInfo(fileDetails);
41    if (hashInfos.empty()) {
42        return false;
43    }
44
45    for (const auto &info : hashInfos) {
46        std::cout << info << "\n";
47    }
48    return true;
49}
50
51bool Hash::FormatFile(const FileDetailMap &fileDetails, const std::string &filePath)
52{
53    std::vector<std::string> hashInfos = Hash::GetHashInfo(fileDetails);
54    if (hashInfos.empty()) {
55        return false;
56    }
57
58    std::ofstream hashFile(filePath, std::ios::out | std::ios ::binary);
59    if (!hashFile.is_open()) {
60        Logger::E(TAG, "failed to open %s", filePath.c_str());
61        return false;
62    }
63
64    for (const auto &info : hashInfos) {
65        hashFile << info << "\n";
66    }
67
68    hashFile.close();
69    return true;
70}
71
72std::vector<std::string> Hash::GetHashInfo(const FileDetailMap &fileDetails)
73{
74    std::vector<std::string> hashInfos;
75    for (const auto &detail : fileDetails) {
76        size_t haskKey = 0;
77        std::stringstream hashInfo;
78        if (!Hash::GenFileHashKey(detail.second.filePath_, haskKey)) {
79            return std::vector<std::string>();
80        }
81        hashInfo << detail.first << ":" << haskKey;
82        hashInfos.push_back(hashInfo.str());
83    }
84
85    return hashInfos;
86}
87
88bool Hash::GenFileHashKey(const std::string &path, size_t &hashKey)
89{
90    std::ifstream fs(path);
91    if (!fs.is_open()) {
92        Logger::E(TAG, "invalid file path '%s'", path.c_str());
93        return false;
94    }
95
96    std::stringstream buffer;
97    buffer << fs.rdbuf();
98
99    hashKey = std::hash<std::string>()(buffer.str());
100    return true;
101}
102} // namespace Idl
103} // namespace OHOS
104