1c893f43dSJason Ling #pragma once
2c893f43dSJason Ling 
3e82d7395SJason Ling #include "fs.hpp"
4cc7f385bSWilliam A. Kennington III #include "handler_config.hpp"
5bec23189SWilliam A. Kennington III #include "status.hpp"
6c893f43dSJason Ling 
7c893f43dSJason Ling #include <nlohmann/json.hpp>
8c893f43dSJason Ling 
9c893f43dSJason Ling #include <memory>
10c893f43dSJason Ling #include <string>
11c893f43dSJason Ling #include <vector>
12c893f43dSJason Ling 
13c893f43dSJason Ling namespace ipmi_flash
14c893f43dSJason Ling {
15e82d7395SJason Ling /**
16e82d7395SJason Ling  * build a systemd file triggerable action from json data
17e82d7395SJason Ling  */
18c893f43dSJason Ling std::unique_ptr<TriggerableActionInterface>
19c893f43dSJason Ling     buildFileSystemd(const nlohmann::json& data);
20c893f43dSJason Ling 
21e82d7395SJason Ling /**
22e82d7395SJason Ling  * build a systemd triggerable action from json data
23e82d7395SJason Ling  */
24c893f43dSJason Ling std::unique_ptr<TriggerableActionInterface>
25c893f43dSJason Ling     buildSystemd(const nlohmann::json& data);
26c893f43dSJason Ling 
27*d0dc723dSWilliam A. Kennington III extern const std::vector<const char*> defaultConfigPaths;
28*d0dc723dSWilliam A. Kennington III 
29c893f43dSJason Ling /* HandlersBuilderIfc is a helper class that builds Handlers from the json files
30c893f43dSJason Ling  * found within a specified directory.
31c893f43dSJason Ling  * The child class that inherits from HandlersBuilderIfc should implement
32c893f43dSJason Ling  * buildHandlersConfigs to perform json validation and parsing.
33c893f43dSJason Ling  *
34c893f43dSJason Ling  */
35c893f43dSJason Ling template <typename T>
3663fd9321SWilliam A. Kennington III struct HandlersBuilderIfc
37c893f43dSJason Ling {
3863fd9321SWilliam A. Kennington III     virtual ~HandlersBuilderIfc() = default;
3963fd9321SWilliam A. Kennington III 
40c893f43dSJason Ling     /**
41*d0dc723dSWilliam A. Kennington III      * Builds configurations from the default set of paths used by the blob
42*d0dc723dSWilliam A. Kennington III      * handler.
43*d0dc723dSWilliam A. Kennington III      */
44*d0dc723dSWilliam A. Kennington III     std::vector<HandlerConfig<T>> buildHandlerConfigsFromDefaultPaths()
45*d0dc723dSWilliam A. Kennington III     {
46*d0dc723dSWilliam A. Kennington III         std::vector<HandlerConfig<T>> ret;
47*d0dc723dSWilliam A. Kennington III         for (auto path : defaultConfigPaths)
48*d0dc723dSWilliam A. Kennington III         {
49*d0dc723dSWilliam A. Kennington III             auto tmp = buildHandlerConfigs(path);
50*d0dc723dSWilliam A. Kennington III             std::move(tmp.begin(), tmp.end(), std::back_inserter(ret));
51*d0dc723dSWilliam A. Kennington III         }
52*d0dc723dSWilliam A. Kennington III         return ret;
53*d0dc723dSWilliam A. Kennington III     }
54*d0dc723dSWilliam A. Kennington III 
55*d0dc723dSWilliam A. Kennington III     /**
56c893f43dSJason Ling      * Given a folder of json configs, build the configurations.
57c893f43dSJason Ling      *
58c893f43dSJason Ling      * @param[in] directory - the directory to search (recurisvely).
59c893f43dSJason Ling      * @return list of HandlerConfig objects.
60c893f43dSJason Ling      */
61*d0dc723dSWilliam A. Kennington III     std::vector<HandlerConfig<T>> buildHandlerConfigs(const char* directory)
62e82d7395SJason Ling     {
63e82d7395SJason Ling 
64e82d7395SJason Ling         std::vector<HandlerConfig<T>> output;
65e82d7395SJason Ling 
66e82d7395SJason Ling         std::vector<std::string> jsonPaths = GetJsonList(directory);
67e82d7395SJason Ling         for (const auto& path : jsonPaths)
68e82d7395SJason Ling         {
69e82d7395SJason Ling             std::ifstream jsonFile(path);
70e82d7395SJason Ling             if (!jsonFile.is_open())
71e82d7395SJason Ling             {
72e82d7395SJason Ling                 std::fprintf(stderr, "Unable to open json file: %s\n",
73e82d7395SJason Ling                              path.c_str());
74e82d7395SJason Ling                 continue;
75e82d7395SJason Ling             }
76e82d7395SJason Ling 
77e82d7395SJason Ling             auto data = nlohmann::json::parse(jsonFile, nullptr, false);
78e82d7395SJason Ling             if (data.is_discarded())
79e82d7395SJason Ling             {
80e82d7395SJason Ling                 std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str());
81e82d7395SJason Ling                 continue;
82e82d7395SJason Ling             }
83e82d7395SJason Ling 
84e82d7395SJason Ling             std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data);
85e82d7395SJason Ling             std::move(configs.begin(), configs.end(),
86e82d7395SJason Ling                       std::back_inserter(output));
87e82d7395SJason Ling         }
88e82d7395SJason Ling         return output;
89e82d7395SJason Ling     };
9063fd9321SWilliam A. Kennington III 
91c893f43dSJason Ling     /**
92c893f43dSJason Ling      * Given a list of handlers as json data, construct the appropriate
93c893f43dSJason Ling      * HandlerConfig objects.  This method is meant to be called per json
94c893f43dSJason Ling      * configuration file found.
95c893f43dSJason Ling      *
96c893f43dSJason Ling      * The list will only contain validly build HandlerConfig objects.  Any
97c893f43dSJason Ling      * invalid configuration is skipped. The hope is that the BMC firmware
98c893f43dSJason Ling      * update configuration will never be invalid, but if another aspect is
99c893f43dSJason Ling      * invalid, it can be fixed with a BMC firmware update once the bug is
100c893f43dSJason Ling      * identified.
101c893f43dSJason Ling      *
102c893f43dSJason Ling      * This code does not validate that the blob specified is unique, that
103c893f43dSJason Ling      * should be handled at a higher layer.
104c893f43dSJason Ling      *
105c893f43dSJason Ling      * @param[in] data - json data from a json file.
106c893f43dSJason Ling      * @return list of HandlerConfig objects.
107c893f43dSJason Ling      */
108c893f43dSJason Ling     virtual std::vector<HandlerConfig<T>>
109c893f43dSJason Ling         buildHandlerFromJson(const nlohmann::json& data) = 0;
110c893f43dSJason Ling };
111c893f43dSJason Ling } // namespace ipmi_flash
112