Add a class to handle ExternalStorer file writes.

Signed-off-by: Kasun Athukorala <kasunath@google.com>
Change-Id: Ic1092a6a1da3375f595774018abfecd08a3cb7d8
diff --git a/include/rde/external_storer_file.hpp b/include/rde/external_storer_file.hpp
new file mode 100644
index 0000000..3d12dc9
--- /dev/null
+++ b/include/rde/external_storer_file.hpp
@@ -0,0 +1,139 @@
+#pragma once
+
+#include "external_storer_interface.hpp"
+#include "nlohmann/json.hpp"
+
+#include <boost/uuid/uuid_generators.hpp>
+
+#include <filesystem>
+#include <string>
+
+namespace bios_bmc_smm_error_logger
+{
+namespace rde
+{
+
+/**
+ * @brief Simple Base class for writing JSON data to files.
+ *
+ * This class allows us to unit test the ExternalStorerFileInterface
+ * functionality.
+ */
+class FileHandlerInterface
+{
+  public:
+    virtual ~FileHandlerInterface() = default;
+
+    /**
+     * @brief Create a folder at the provided path.
+     *
+     * @param[in] folderPath - folder path.
+     * @return true if successful.
+     */
+    virtual bool createFolder(const std::string& folderPath) const = 0;
+
+    /**
+     * @brief Create an index.json and write the JSON content to it.
+     *
+     * If the file already exists, this will overwrite it.
+     *
+     * @param[in] folderPath - path of the file without including the file name.
+     * @param[in] jsonPdr - PDR in nlohmann::json format.
+     * @return true if successful.
+     */
+    virtual bool createFile(const std::string& folderPath,
+                            const nlohmann::json& jsonPdr) const = 0;
+};
+
+/**
+ * @brief Class for handling folder and file creation for ExternalStorer.
+ */
+class ExternalStorerFileWriter : public FileHandlerInterface
+{
+  public:
+    bool createFolder(const std::string& folderPath) const override;
+    bool createFile(const std::string& folderPath,
+                    const nlohmann::json& jsonPdr) const override;
+};
+
+/**
+ * @brief Categories for different redfish JSON strings.
+ */
+enum class JsonPdrType
+{
+    logEntry,
+    logService,
+    other
+};
+
+/**
+ * @brief Class for handling ExternalStorer file operations.
+ */
+class ExternalStorerFileInterface : public ExternalStorerInterface
+{
+  public:
+    /**
+     * @brief Constructor for the ExternalStorerFileInterface.
+     *
+     * @param[in] rootPath - root path for creating redfish folders.
+     * Eg: "/run/bmcweb"
+     * @param[in] fileHandler - an ExternalStorerFileWriter object. This class
+     * will take the ownership of this object.
+     */
+    ExternalStorerFileInterface(
+        std::string_view rootPath,
+        std::unique_ptr<FileHandlerInterface> fileHandler);
+
+    bool publishJson(std::string_view jsonStr) override;
+
+  private:
+    std::string rootPath;
+    std::unique_ptr<FileHandlerInterface> fileHandler;
+    std::string logServiceId;
+    boost::uuids::random_generator randomGen;
+
+    /**
+     * @brief Get the type of the received PDR.
+     *
+     * @param[in] jsonSchema - PDR in nlohmann::json format.
+     * @return JsonPdrType of the PDR.
+     */
+    JsonPdrType getSchemaType(const nlohmann::json& jsonSchema) const;
+
+    /**
+     * @brief Process a LogEntry type PDR.
+     *
+     * @param[in] logEntry - PDR in nlohmann::json format.
+     * @return true if successful.
+     */
+    bool processLogEntry(nlohmann::json& logEntry);
+
+    /**
+     * @brief Process a LogService type PDR.
+     *
+     * @param[in] logService - PDR in nlohmann::json format.
+     * @return true if successful.
+     */
+    bool processLogService(const nlohmann::json& logService);
+
+    /**
+     * @brief Process PDRs that doesn't have a specific category.
+     *
+     * @param[in] jsonPdr - PDR in nlohmann::json format.
+     * @return true if successful.
+     */
+    bool processOtherTypes(const nlohmann::json& jsonPdr) const;
+
+    /**
+     * @brief Create the needed folders and the index.json.
+     *
+     * @param subPath - path within the root folder.
+     * @param jsonPdr - PDR in nlohmann::json format.
+     * @return true if successful.
+     */
+    bool createFile(const std::string& subPath,
+                    const nlohmann::json& jsonPdr) const;
+};
+
+} // namespace rde
+} // namespace bios_bmc_smm_error_logger
diff --git a/include/rde/external_storer_interface.hpp b/include/rde/external_storer_interface.hpp
new file mode 100644
index 0000000..05a8616
--- /dev/null
+++ b/include/rde/external_storer_interface.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <string_view>
+
+namespace bios_bmc_smm_error_logger
+{
+namespace rde
+{
+
+/**
+ * @brief Base class for publishing data to ExternalStorer.
+ */
+class ExternalStorerInterface
+{
+  public:
+    virtual ~ExternalStorerInterface() = default;
+
+    /**
+     * @brief Publish JSON string to ExternalStorer.
+     *
+     * @param[in] jsonStr - a valid JSON string.
+     * @return true if successful.
+     */
+    virtual bool publishJson(std::string_view jsonStr) = 0;
+};
+
+} // namespace rde
+} // namespace bios_bmc_smm_error_logger