1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include "ServiceManager.hpp"
6#include "units/template.hpp"
7
8#include <memory>
9#include <toml++/impl/table.hpp>
10#include <toml++/toml.hpp>
11#include <vector>
12
13class ConfigurationManagerImpl
14{
15 public:
16 ConfigurationManagerImpl() = default;
17 ~ConfigurationManagerImpl() = default;
18
19 void LoadConfiguration(std::vector<toml::table> &&tables);
20 void FinaliseConfiguration();
21
22 inline std::string GetDefaultTarget() const
23 {
24 return defaultTarget;
25 }
26
27 bool HasUnit(const std::string &id) const
28 {
29 const auto [units, lock] = units_.BeginRead();
30 return units.contains(id);
31 }
32
33 bool HasUnitConfig(const std::string &id) const
34 {
35 const auto [units, lock] = unitConfig_.BeginRead();
36 return units.contains(id);
37 }
38
39 bool HasTemplate(const std::string &id) const
40 {
41 const auto [templates, lock] = templates_.BeginRead();
42 return templates.contains(id);
43 }
44
45 bool HasTemplateConfig(const std::string &id) const
46 {
47 const auto [templates, lock] = templateConfig_.BeginRead();
48 return templates.contains(id);
49 }
50
51 std::map<std::string, std::shared_ptr<IUnit>> GetAllUnits() const
52 {
53 return units_.Clone();
54 }
55
56 std::map<std::string, std::shared_ptr<Template>> GetAllTemplates() const
57 {
58 return templates_.Clone();
59 }
60
61 std::shared_ptr<IUnit> GetUnit(const std::string &id) const
62 {
63 const auto [units, lock] = units_.BeginRead();
64 if (units.contains(id))
65 return units.at(id);
66 return nullptr;
67 }
68
69 template<typename TUnit>
70 requires(std::derived_from<TUnit, Unit> && !std::is_same_v<TUnit, Unit>) std::shared_ptr<TUnit> GetUnit(const std::string &id) const
71 {
72 const auto [units, lock] = units_.BeginRead();
73 if (units.contains(id))
74 return std::dynamic_pointer_cast<TUnit>(units.at(id));
75 return nullptr;
76 }
77
78 std::shared_ptr<Template> GetTemplate(const std::string &id) const
79 {
80 const auto [templates, lock] = templates_.BeginRead();
81 if (templates.contains(id))
82 return templates.at(id);
83 return nullptr;
84 }
85
86 std::optional<toml::table> GetTemplateConfig(const std::string &id) const
87 {
88 const auto [templates, lock] = templateConfig_.BeginRead();
89 if (templates.contains(id))
90 return templates.at(id);
91 return std::nullopt;
92 }
93
94 std::map<std::pair<std::string, ArgumentMap>, std::string> GetTemplateOverrides() const
95 {
96 return templateOverrides_.Clone();
97 }
98
99 std::vector<std::pair<std::string, ArgumentMap>> LookupTemplate(const std::string &id, const ArgumentMap &args);
100
101 std::shared_ptr<IUnit> InstantiateUnit(const std::string &template_id, const ArgumentMap &parameters);
102
103 void AddUnit(std::shared_ptr<IUnit> unit);
104
105 private:
106 [[nodiscard]] bool FillInheritanceRecursive(const std::string &inherits, toml::table &table, ArgumentMap &args) const;
107 std::shared_ptr<Template> DoCreateTemplate(const std::string &id) const;
108
109 private:
110 std::string defaultTarget;
111
112 Locked<std::map<std::string, toml::table>> templateConfig_;
113 Locked<std::map<std::string, toml::table>> unitConfig_;
114
115 Locked<std::map<std::string, std::shared_ptr<Template>>> templates_;
116 Locked<std::map<std::string, std::shared_ptr<IUnit>>> units_;
117
118 Locked<std::map<std::pair<std::string, ArgumentMap>, std::string>> templateOverrides_;
119};
120
121const inline std::unique_ptr<ConfigurationManagerImpl> ConfigurationManager = std::make_unique<ConfigurationManagerImpl>();
122