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