1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "config.h"
17#include <thread>
18#include "common/common_macro.h"
19#include "common/event_comm.h"
20#include "common/media_log.h"
21#include "json_parser.h"
22
23namespace OHOS {
24namespace Sharing {
25int32_t Config::GetConfig(SharingData::Ptr &datas)
26{
27    SHARING_LOGD("trace.");
28    datas = datas_;
29    return CONFIGURE_ERROR_NONE;
30}
31
32int32_t Config::GetConfig(const std::string &module, SharingDataGroupByModule::Ptr &values)
33{
34    SHARING_LOGD("trace.");
35    std::shared_lock<std::shared_mutex> lk(mutex_);
36    if (datas_ == nullptr || !datas_->HasModule(module)) {
37        SHARING_LOGE("data_s is null or has no module named %{public}s.", module.c_str());
38        return CONFIGURE_ERROR_NOT_FIND;
39    }
40
41    return datas_->GetSharingValues(values, module);
42}
43
44int32_t Config::GetConfig(const std::string &module, const std::string &tag, SharingDataGroupByTag::Ptr &values)
45{
46    SHARING_LOGD("trace.");
47    SharingDataGroupByModule::Ptr modelValue = nullptr;
48    if (GetConfig(module, modelValue) != CONFIGURE_ERROR_NONE) {
49        SHARING_LOGE("module %{public}s error.", module.c_str());
50        return CONFIGURE_ERROR_NOT_FIND;
51    }
52
53    std::shared_lock<std::shared_mutex> lk(mutex_);
54    return datas_->GetSharingValues(values, module, tag);
55}
56
57int32_t Config::GetConfig(const std::string &module, const std::string &tag, const std::string &key,
58                          SharingValue::Ptr &value)
59{
60    SHARING_LOGD("trace.");
61    SharingDataGroupByTag::Ptr tagValue = nullptr;
62    if (GetConfig(module, tag, tagValue) != CONFIGURE_ERROR_NONE) {
63        SHARING_LOGE("module %{public}s, tag %{public}s error.", module.c_str(), tag.c_str());
64        return CONFIGURE_ERROR_NOT_FIND;
65    }
66
67    std::shared_lock<std::shared_mutex> lk(mutex_);
68    SharingValue::Ptr valueTmp = datas_->GetSharingValue(key, module, tag);
69    if (valueTmp == nullptr) {
70        SHARING_LOGE("sharing value is null.");
71        return CONFIGURE_ERROR_NOT_FIND;
72    }
73
74    value = valueTmp;
75    return CONFIGURE_ERROR_NONE;
76}
77
78int32_t Config::SetConfig(const SharingData::Ptr &datas)
79{
80    SHARING_LOGD("trace.");
81    datas_ = datas;
82    SaveConfig();
83    return CONFIGURE_ERROR_NONE;
84}
85
86int32_t Config::SetConfig(const std::string &module, const SharingDataGroupByModule::Ptr &values)
87{
88    SHARING_LOGD("trace.");
89    std::unique_lock<std::shared_mutex> lk(mutex_);
90    RETURN_INVALID_IF_NULL(datas_);
91    auto err = datas_->PutSharingValues(values, module);
92    if (err == CONFIGURE_ERROR_NONE) {
93        SaveConfig();
94    }
95
96    return err;
97}
98
99int32_t Config::SetConfig(const std::string &module, const std::string &tag, const SharingDataGroupByTag::Ptr &values)
100{
101    SHARING_LOGD("trace.");
102    SharingDataGroupByModule::Ptr modelValue = nullptr;
103    if (GetConfig(module, modelValue) != CONFIGURE_ERROR_NONE) {
104        modelValue = std::make_shared<SharingDataGroupByModule>(module);
105    }
106
107    if (modelValue == nullptr) {
108        SHARING_LOGE("modelValue value is null.");
109        return CONFIGURE_ERROR_NOT_FIND;
110    }
111
112    std::unique_lock<std::shared_mutex> lk(mutex_);
113    auto err = modelValue->PutSharingValues(tag, values);
114    if (err == CONFIGURE_ERROR_NONE) {
115        SaveConfig();
116    }
117
118    return err;
119}
120
121int32_t Config::SetConfig(const std::string &module, const std::string &tag, const std::string &key,
122                          const SharingValue::Ptr &value)
123{
124    SHARING_LOGD("trace.");
125    RETURN_INVALID_IF_NULL(datas_);
126    if (!datas_->HasModule(module)) {
127        auto modelValue = std::make_shared<SharingDataGroupByModule>(module);
128        modelValue->PutSharingValue(tag, key, value);
129        return SetConfig(module, modelValue);
130    }
131
132    if (!datas_->HasTag(module, tag)) {
133        auto tagValue = std::make_shared<SharingDataGroupByTag>(tag);
134        tagValue->PutSharingValue(key, value);
135        return SetConfig(module, tag, tagValue);
136    }
137
138    datas_->PutSharingValue(key, value, module, tag);
139    SaveConfig();
140    return CONFIGURE_ERROR_NONE;
141}
142
143bool Config::ReadConfig(void)
144{
145    SHARING_LOGD("trace.");
146    std::thread read([this] {
147        std::unique_lock<std::shared_mutex> lock(mutex_);
148        status_ = ConfigStatus::CONFIG_STATUS_READING;
149        JsonParser parser;
150        parser.GetConfig(fileName_, datas_);
151        status_ = ConfigStatus::CONFIG_STATUS_READY;
152        EmitEvent();
153    });
154
155    if (read.joinable()) {
156        read.join();
157    }
158
159    return true;
160}
161
162bool Config::SaveConfig(void)
163{
164    SHARING_LOGD("trace.");
165    std::thread read([this] {
166        std::unique_lock<std::shared_mutex> lock(mutex_);
167        status_ = ConfigStatus::CONFIG_STATUS_WRITING;
168        JsonParser parser;
169        std::string ofile = "/data/sharing_config.json";
170        parser.SaveConfig(ofile, datas_);
171        status_ = ConfigStatus::CONFIG_STATUS_READY;
172    });
173
174    read.detach();
175    return true;
176}
177
178void Config::EmitEvent(const ConfigStatus type, const ModuleType toModule)
179{
180    SHARING_LOGD("trace.");
181    SharingEvent evt;
182    evt.eventMsg = std::make_shared<ConfigEventMsg>(type, toModule);
183    evt.eventMsg->type = EventType::EVENT_CONFIGURE_READY;
184    emiter_.SendEvent(evt);
185}
186
187void Config::EmitEvent(const EventType type, const ModuleType toModule, const SharingDataGroupByModule::Ptr &data)
188{
189    SHARING_LOGD("trace.");
190    SharingEvent evt;
191    evt.eventMsg = std::make_shared<ConfigEventMsg>(data, toModule);
192    evt.eventMsg->type = type;
193    emiter_.SendEvent(evt);
194}
195
196void Config::Init(void)
197{
198    SHARING_LOGD("trace.");
199    {
200        std::unique_lock<std::shared_mutex> lock(mutex_);
201        if (status_ != ConfigStatus::CONFIG_STATUS_INVALID) {
202            SHARING_LOGE("init CONFIG_STATUS_INVALID.");
203            return;
204        }
205        status_ = ConfigStatus::CONFIG_STATUS_INITED;
206    }
207
208    ReadConfig();
209}
210
211} // namespace Sharing
212} // namespace OHOS