1693eaed0SAndrew Geissler #include <cassert>
2693eaed0SAndrew Geissler #include <fstream>
3693eaed0SAndrew Geissler #include <iostream>
4693eaed0SAndrew Geissler #include <systemd_target_parser.hpp>
5693eaed0SAndrew Geissler 
6693eaed0SAndrew Geissler void validateErrorsToMonitor(std::vector<std::string>& errorsToMonitor)
7693eaed0SAndrew Geissler {
8693eaed0SAndrew Geissler     assert(errorsToMonitor.size());
9693eaed0SAndrew Geissler 
10693eaed0SAndrew Geissler     const std::vector<std::string> validErrorsToMonitor = {
11693eaed0SAndrew Geissler         "default", "timeout", "failed", "dependency"};
12693eaed0SAndrew Geissler     for (const auto& errorToMonitor : errorsToMonitor)
13693eaed0SAndrew Geissler     {
14693eaed0SAndrew Geissler         if (std::find(validErrorsToMonitor.begin(), validErrorsToMonitor.end(),
15693eaed0SAndrew Geissler                       errorToMonitor) == validErrorsToMonitor.end())
16693eaed0SAndrew Geissler         {
17693eaed0SAndrew Geissler             throw std::out_of_range("Found invalid error to monitor");
18693eaed0SAndrew Geissler         }
19693eaed0SAndrew Geissler     }
20*75a2614fSAndrew Geissler     // See if default was in the errors to monitor, if so replace with defaults
21*75a2614fSAndrew Geissler     auto errorItr =
22*75a2614fSAndrew Geissler         std::find(errorsToMonitor.begin(), errorsToMonitor.end(), "default");
23*75a2614fSAndrew Geissler     if (errorItr != errorsToMonitor.end())
24*75a2614fSAndrew Geissler     {
25*75a2614fSAndrew Geissler         // Verify default is the only entry
26*75a2614fSAndrew Geissler         if (errorsToMonitor.size() != 1)
27*75a2614fSAndrew Geissler         {
28*75a2614fSAndrew Geissler             throw std::invalid_argument(
29*75a2614fSAndrew Geissler                 "default must be only error to monitor");
30*75a2614fSAndrew Geissler         }
31*75a2614fSAndrew Geissler         // delete "default" and insert defaults
32*75a2614fSAndrew Geissler         errorsToMonitor.erase(errorItr);
33*75a2614fSAndrew Geissler         errorsToMonitor.push_back("timeout");
34*75a2614fSAndrew Geissler         errorsToMonitor.push_back("failed");
35*75a2614fSAndrew Geissler         errorsToMonitor.push_back("dependency");
36*75a2614fSAndrew Geissler     }
37693eaed0SAndrew Geissler }
38693eaed0SAndrew Geissler 
39693eaed0SAndrew Geissler TargetErrorData parseFiles(const std::vector<std::string>& filePaths)
40693eaed0SAndrew Geissler {
41693eaed0SAndrew Geissler     TargetErrorData systemdTargetMap;
42693eaed0SAndrew Geissler     for (const auto& jsonFile : filePaths)
43693eaed0SAndrew Geissler     {
44693eaed0SAndrew Geissler         if (gVerbose)
45693eaed0SAndrew Geissler         {
46693eaed0SAndrew Geissler             std::cout << "Parsing input file " << jsonFile << std::endl;
47693eaed0SAndrew Geissler         }
48693eaed0SAndrew Geissler         std::ifstream fileStream(jsonFile);
49693eaed0SAndrew Geissler         auto j = json::parse(fileStream);
50693eaed0SAndrew Geissler 
51693eaed0SAndrew Geissler         for (auto it = j["targets"].begin(); it != j["targets"].end(); ++it)
52693eaed0SAndrew Geissler         {
53693eaed0SAndrew Geissler             targetEntry entry;
54693eaed0SAndrew Geissler             if (gVerbose)
55693eaed0SAndrew Geissler             {
56693eaed0SAndrew Geissler                 std::cout << "target: " << it.key() << " | " << it.value()
57693eaed0SAndrew Geissler                           << std::endl;
58693eaed0SAndrew Geissler             }
59693eaed0SAndrew Geissler 
60693eaed0SAndrew Geissler             // Be unforgiving on invalid json files. Just throw or allow
61693eaed0SAndrew Geissler             // nlohmann to throw an exception if something is off
62693eaed0SAndrew Geissler             auto errorsToMonitor = it.value().find("errorsToMonitor");
63693eaed0SAndrew Geissler             entry.errorsToMonitor =
64693eaed0SAndrew Geissler                 errorsToMonitor->get<std::vector<std::string>>();
65693eaed0SAndrew Geissler 
66693eaed0SAndrew Geissler             validateErrorsToMonitor(entry.errorsToMonitor);
67693eaed0SAndrew Geissler 
68693eaed0SAndrew Geissler             auto errorToLog = it.value().find("errorToLog");
69693eaed0SAndrew Geissler             entry.errorToLog = errorToLog->get<std::string>();
70693eaed0SAndrew Geissler 
71693eaed0SAndrew Geissler             systemdTargetMap[it.key()] = entry;
72693eaed0SAndrew Geissler         }
73693eaed0SAndrew Geissler     }
74693eaed0SAndrew Geissler     return systemdTargetMap;
75693eaed0SAndrew Geissler }
76