1c893f43dSJason Ling #pragma once
2c893f43dSJason Ling 
3e82d7395SJason Ling #include "fs.hpp"
4c893f43dSJason Ling #include "general_systemd.hpp"
5c893f43dSJason Ling #include "image_handler.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 
27c893f43dSJason Ling /**
28c893f43dSJason Ling  * HandlerConfig associates a blobID with an ImageHandler and a set of
29c893f43dSJason Ling  * supported actions of type T.
30c893f43dSJason Ling  */
31c893f43dSJason Ling template <typename T>
32*63fd9321SWilliam A. Kennington III struct HandlerConfig
33c893f43dSJason Ling {
34c893f43dSJason Ling     /* A string in the form: /flash/{unique}, s.t. unique is something like,
35c893f43dSJason Ling      * flash, ubitar, statictar, or bios
36c893f43dSJason Ling      */
37c893f43dSJason Ling     std::string blobId;
38c893f43dSJason Ling 
39c893f43dSJason Ling     /* This owns a handler interface, this is typically going to be a file
40c893f43dSJason Ling      * writer object.
41c893f43dSJason Ling      */
42c893f43dSJason Ling     std::unique_ptr<ImageHandlerInterface> handler;
43c893f43dSJason Ling 
44c893f43dSJason Ling     /*  specifies actions to be taken in response to certain operations on a
45c893f43dSJason Ling      *  blob.
46c893f43dSJason Ling      *  Usually required but there are exceptions;  the hashBlobId doesn't have
47c893f43dSJason Ling      * an action pack.
48c893f43dSJason Ling      */
49c893f43dSJason Ling     std::unique_ptr<T> actions;
50c893f43dSJason Ling };
51c893f43dSJason Ling 
52c893f43dSJason Ling /* HandlersBuilderIfc is a helper class that builds Handlers from the json files
53c893f43dSJason Ling  * found within a specified directory.
54c893f43dSJason Ling  * The child class that inherits from HandlersBuilderIfc should implement
55c893f43dSJason Ling  * buildHandlersConfigs to perform json validation and parsing.
56c893f43dSJason Ling  *
57c893f43dSJason Ling  */
58c893f43dSJason Ling template <typename T>
59*63fd9321SWilliam A. Kennington III struct HandlersBuilderIfc
60c893f43dSJason Ling {
61*63fd9321SWilliam A. Kennington III     virtual ~HandlersBuilderIfc() = default;
62*63fd9321SWilliam A. Kennington III 
63c893f43dSJason Ling     /**
64c893f43dSJason Ling      * Given a folder of json configs, build the configurations.
65c893f43dSJason Ling      *
66c893f43dSJason Ling      * @param[in] directory - the directory to search (recurisvely).
67c893f43dSJason Ling      * @return list of HandlerConfig objects.
68c893f43dSJason Ling      */
69c893f43dSJason Ling     std::vector<HandlerConfig<T>>
70e82d7395SJason Ling         buildHandlerConfigs(const std::string& directory)
71e82d7395SJason Ling     {
72e82d7395SJason Ling 
73e82d7395SJason Ling         std::vector<HandlerConfig<T>> output;
74e82d7395SJason Ling 
75e82d7395SJason Ling         std::vector<std::string> jsonPaths = GetJsonList(directory);
76e82d7395SJason Ling         for (const auto& path : jsonPaths)
77e82d7395SJason Ling         {
78e82d7395SJason Ling             std::ifstream jsonFile(path);
79e82d7395SJason Ling             if (!jsonFile.is_open())
80e82d7395SJason Ling             {
81e82d7395SJason Ling                 std::fprintf(stderr, "Unable to open json file: %s\n",
82e82d7395SJason Ling                              path.c_str());
83e82d7395SJason Ling                 continue;
84e82d7395SJason Ling             }
85e82d7395SJason Ling 
86e82d7395SJason Ling             auto data = nlohmann::json::parse(jsonFile, nullptr, false);
87e82d7395SJason Ling             if (data.is_discarded())
88e82d7395SJason Ling             {
89e82d7395SJason Ling                 std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str());
90e82d7395SJason Ling                 continue;
91e82d7395SJason Ling             }
92e82d7395SJason Ling 
93e82d7395SJason Ling             std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data);
94e82d7395SJason Ling             std::move(configs.begin(), configs.end(),
95e82d7395SJason Ling                       std::back_inserter(output));
96e82d7395SJason Ling         }
97e82d7395SJason Ling         return output;
98e82d7395SJason Ling     };
99*63fd9321SWilliam A. Kennington III 
100c893f43dSJason Ling     /**
101c893f43dSJason Ling      * Given a list of handlers as json data, construct the appropriate
102c893f43dSJason Ling      * HandlerConfig objects.  This method is meant to be called per json
103c893f43dSJason Ling      * configuration file found.
104c893f43dSJason Ling      *
105c893f43dSJason Ling      * The list will only contain validly build HandlerConfig objects.  Any
106c893f43dSJason Ling      * invalid configuration is skipped. The hope is that the BMC firmware
107c893f43dSJason Ling      * update configuration will never be invalid, but if another aspect is
108c893f43dSJason Ling      * invalid, it can be fixed with a BMC firmware update once the bug is
109c893f43dSJason Ling      * identified.
110c893f43dSJason Ling      *
111c893f43dSJason Ling      * This code does not validate that the blob specified is unique, that
112c893f43dSJason Ling      * should be handled at a higher layer.
113c893f43dSJason Ling      *
114c893f43dSJason Ling      * @param[in] data - json data from a json file.
115c893f43dSJason Ling      * @return list of HandlerConfig objects.
116c893f43dSJason Ling      */
117c893f43dSJason Ling     virtual std::vector<HandlerConfig<T>>
118c893f43dSJason Ling         buildHandlerFromJson(const nlohmann::json& data) = 0;
119c893f43dSJason Ling };
120c893f43dSJason Ling } // namespace ipmi_flash
121