1//! @file configure.hpp
2//! @author ryftchen
3//! @brief The declarations (configure) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2025 ryftchen. All rights reserved.
6
7#pragma once
8
9#include "utility/include/json.hpp"
10#include "utility/include/macro.hpp"
11#include "utility/include/memory.hpp"
12#include "utility/include/thread.hpp"
13
14//! @brief The application module.
15namespace application // NOLINT(modernize-concat-nested-namespaces)
16{
17//! @brief Configuration-related functions in the application module.
18namespace configure
19{
20//! @brief The literal string of the field.
21namespace field
22{
23//! @brief The literal string of the "activateHelper" field.
24constexpr const char* const activateHelper = MACRO_STRINGIFY(activateHelper);
25//! @brief The literal string of the "helperList" field.
26constexpr const char* const helperList = MACRO_STRINGIFY(helperList);
27//! @brief The literal string of the "properties" field in the object of "helpList".
28constexpr const char* const properties = MACRO_STRINGIFY(properties);
29//! @brief The literal string of the "required" field in the object of "helpList".
30constexpr const char* const required = MACRO_STRINGIFY(required);
31//! @brief The literal string of the "logger" field of "helpList".
32constexpr const char* const logger = MACRO_STRINGIFY(logger);
33//! @brief The literal string of the "filePath" field in the properties of "logger" object of "helpList".
34constexpr const char* const filePath = MACRO_STRINGIFY(filePath);
35//! @brief The literal string of the "priorityLevel" field in the properties of "logger" object of "helpList".
36constexpr const char* const priorityLevel = MACRO_STRINGIFY(priorityLevel);
37//! @brief The literal string of the "targetType" field in the properties of "logger" object of "helpList".
38constexpr const char* const targetType = MACRO_STRINGIFY(targetType);
39//! @brief The literal string of the "writeMode" field in the properties of "logger" object of "helpList".
40constexpr const char* const writeMode = MACRO_STRINGIFY(writeMode);
41//! @brief The literal string of the "viewer" field of "helpList".
42constexpr const char* const viewer = MACRO_STRINGIFY(viewer);
43//! @brief The literal string of the "tcpHost" field in the properties of "viewer" object of "helpList".
44constexpr const char* const tcpHost = MACRO_STRINGIFY(tcpHost);
45//! @brief The literal string of the "tcpPort" field in the properties of "viewer" object of "helpList".
46constexpr const char* const tcpPort = MACRO_STRINGIFY(tcpPort);
47//! @brief The literal string of the "udpHost" field in the properties of "viewer" object of "helpList".
48constexpr const char* const udpHost = MACRO_STRINGIFY(udpHost);
49//! @brief The literal string of the "udpPort" field in the properties of "viewer" object of "helpList".
50constexpr const char* const udpPort = MACRO_STRINGIFY(udpPort);
51//! @brief The literal string of the "helperTimeout" field.
52constexpr const char* const helperTimeout = MACRO_STRINGIFY(helperTimeout);
53} // namespace field
54
55//! @brief Maximum access limit.
56constexpr std::uint8_t maxAccessLimit = 10;
57//! @brief Default configuration filename.
58constexpr std::string_view defaultConfigFile = "configure/foo.json";
59//! @brief Get the full path to the configuration file.
60//! @param filename - configuration file path
61//! @return full path to the configuration file
62std::string getFullConfigPath(const std::string_view filename = defaultConfigFile);
63
64//! @brief Configuration.
65class Configure final
66{
67public:
68 //! @brief Destroy the Configure object.
69 ~Configure() = default;
70 //! @brief Construct a new Configure object.
71 Configure(const Configure&) = delete;
72 //! @brief Construct a new Configure object.
73 Configure(Configure&&) = delete;
74 //! @brief The operator (=) overloading of Configure class.
75 //! @return reference of the Configure object
76 Configure& operator=(const Configure&) = delete;
77 //! @brief The operator (=) overloading of Configure class.
78 //! @return reference of the Configure object
79 Configure& operator=(Configure&&) = delete;
80
81 friend const Configure& getInstance(const std::string_view filename);
82
83private:
84 //! @brief Construct a new Configure object.
85 //! @param filename - configure file path
86 explicit Configure(const std::string_view filename) :
87 filePath{getFullConfigPath(filename)}, dataRepo(parseConfigFile(configFile: filePath))
88 {
89 }
90
91 //! @brief Full path to the configuration file.
92 const std::string filePath;
93 //! @brief Configuration data repository.
94 const utility::json::JSON dataRepo;
95
96 friend class Retrieve;
97 //! @brief Parse the configuration file.
98 //! @param configFile - configuration file
99 //! @return configuration data
100 static utility::json::JSON parseConfigFile(const std::string_view configFile);
101 //! @brief Verify the configuration data.
102 //! @param configData - configuration data
103 static void verifyConfigData(const utility::json::JSON& configData);
104 //! @brief Check the object in the helper list.
105 //! @tparam Helper - type of helper
106 //! @param helper - object of helper
107 template <typename Helper>
108 static void checkObjectInHelperList(const utility::json::JSON& helper);
109};
110
111//! @brief Guard for retrieve configuration.
112class Retrieve final
113{
114public:
115 //! @brief Construct a new Retrieve object.
116 //! @param sem - semaphore for configuration access control
117 explicit Retrieve(std::counting_semaphore<maxAccessLimit>& sem);
118 //! @brief Destroy the Retrieve object.
119 ~Retrieve();
120 //! @brief Construct a new Retrieve object.
121 Retrieve(const Retrieve&) = delete;
122 //! @brief Construct a new Retrieve object.
123 Retrieve(Retrieve&&) = delete;
124 //! @brief The operator (=) overloading of Retrieve class.
125 //! @return reference of the Retrieve object
126 Retrieve& operator=(const Retrieve&) = delete;
127 //! @brief The operator (=) overloading of Retrieve class.
128 //! @return reference of the Retrieve object
129 Retrieve& operator=(Retrieve&&) = delete;
130
131 //! @brief The operator (/) overloading of Retrieve class.
132 //! @param field - field name
133 //! @return const reference of the JSON object
134 const utility::json::JSON& operator/(const std::string& field) const;
135 //! @brief The operator (()) overloading of Retrieve class.
136 //! @return const reference of the JSON object
137 explicit operator const utility::json::JSON&() const;
138
139private:
140 //! @brief Semaphore that controls the maximum access limit.
141 std::counting_semaphore<maxAccessLimit>& sem;
142};
143
144extern Retrieve retrieveDataRepo();
145extern utility::json::JSON dumpDefaultConfig();
146extern bool loadSettings(const std::string_view filename = defaultConfigFile);
147
148//! @brief Configuration details.
149namespace detail
150{
151//! @brief The operator (/) overloading of JSON class.
152//! @param json - specific JSON object
153//! @param field - field name
154//! @return const reference of the JSON object
155inline const utility::json::JSON& operator/(const utility::json::JSON& json, const std::string& field)
156{
157 return json.at(key: field);
158}
159
160//! @brief Query the "activateHelper" configuration.
161//! @return "activateHelper" configuration
162inline bool activateHelper() noexcept
163{
164 return (retrieveDataRepo() / field::activateHelper).asBoolean();
165}
166//! @brief Query the "filePath" configuration in the properties of "logger" object of "helpList".
167//! @return "filePath" configuration in the properties of "logger" object of "helpList"
168inline std::string filePath4Logger() noexcept
169{
170 return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::filePath).asString();
171}
172//! @brief Query the "priorityLevel" configuration in the properties of "logger" object of "helpList".
173//! @return "priorityLevel" configuration in the properties of "logger" object of "helpList"
174inline int priorityLevel4Logger() noexcept
175{
176 return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::priorityLevel)
177 .asIntegral();
178}
179//! @brief Query the "targetType" configuration in the properties of "logger" object of "helpList".
180//! @return "targetType" configuration in the properties of "logger" object of "helpList"
181inline int targetType4Logger() noexcept
182{
183 return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::targetType)
184 .asIntegral();
185}
186//! @brief Query the "writeMode" configuration in the properties of "logger" object of "helpList".
187//! @return "writeMode" configuration in the properties of "logger" object of "helpList"
188inline int writeMode4Logger() noexcept
189{
190 return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::writeMode).asIntegral();
191}
192//! @brief Query the "tcpHost" configuration in the properties of "viewer" object of "helpList".
193//! @return "tcpHost" configuration in the properties of "viewer" object of "helpList"
194inline std::string tcpHost4Viewer() noexcept
195{
196 return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::tcpHost).asString();
197}
198//! @brief Query the "tcpPort" configuration in the properties of "viewer" object of "helpList".
199//! @return "tcpPort" configuration in the properties of "viewer" object of "helpList"
200inline int tcpPort4Viewer() noexcept
201{
202 return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::tcpPort).asIntegral();
203}
204//! @brief Query the "udpHost" configuration in the properties of "viewer" object of "helpList".
205//! @return "udpHost" configuration in the properties of "viewer" object of "helpList"
206inline std::string udpHost4Viewer() noexcept
207{
208 return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::udpHost).asString();
209}
210//! @brief Query the "udpPort" configuration in the properties of "viewer" object of "helpList".
211//! @return "udpPort" configuration in the properties of "viewer" object of "helpList"
212inline int udpPort4Viewer() noexcept
213{
214 return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::udpPort).asIntegral();
215}
216//! @brief Query the "helperTimeout" configuration.
217//! @return "helperTimeout" configuration
218inline int helperTimeout() noexcept
219{
220 return (retrieveDataRepo() / field::helperTimeout).asIntegral();
221}
222} // namespace detail
223
224//! @brief Activity configuration applied to tasks.
225namespace task
226{
227//! @brief Alias for the memory pool for task when making multi-threading.
228using ResourcePool = utility::memory::Memory<utility::thread::Thread>;
229extern ResourcePool& resourcePool();
230//! @brief Preset full name for the task.
231//! @param cli - sub-cli name
232//! @param cat - category name
233//! @param cho - choice name
234//! @return full name
235inline std::string presetName(const std::string_view cli, const std::string_view cat, const std::string_view cho)
236{
237 return '@' + std::string{cli} + '_' + std::string{cat} + '_' + std::string{cho};
238}
239} // namespace task
240} // namespace configure
241} // namespace application
242