#include "rde/external_storer_file.hpp"

#include <fmt/format.h>

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>

#include <fstream>
#include <string_view>

namespace bios_bmc_smm_error_logger
{
namespace rde
{

bool ExternalStorerFileWriter::createFolder(const std::string& folderPath) const
{
    std::filesystem::path path(folderPath);
    if (!std::filesystem::is_directory(path))
    {
        if (!std::filesystem::create_directories(path))
        {
            fmt::print(stderr, "Failed to create a folder at {}\n", folderPath);
            return false;
        }
    }
    return true;
}

bool ExternalStorerFileWriter::createFile(const std::string& folderPath,
                                          const nlohmann::json& jsonPdr) const
{
    if (!createFolder(folderPath))
    {
        return false;
    }
    std::filesystem::path path(folderPath);
    path /= "index.json";
    // If the file already exist, overwrite it.
    std::ofstream output(path);
    output << jsonPdr;
    output.close();
    return true;
}

ExternalStorerFileInterface::ExternalStorerFileInterface(
    sdbusplus::bus_t& bus, std::string_view rootPath,
    std::unique_ptr<FileHandlerInterface> fileHandler) :
    rootPath(rootPath),
    fileHandler(std::move(fileHandler)), logServiceId(""),
    cperNotifier(std::make_unique<CperFileNotifierHandler>(bus))
{}

bool ExternalStorerFileInterface::publishJson(std::string_view jsonStr)
{
    nlohmann::json jsonDecoded;
    try
    {
        jsonDecoded = nlohmann::json::parse(jsonStr);
    }
    catch (nlohmann::json::parse_error& e)
    {
        fmt::print(stderr, "JSON parse error: \n{}\n", e.what());
        return false;
    }

    // We need to know the type to determine how to process the decoded JSON
    // output.
    if (!jsonDecoded.contains("@odata.type"))
    {
        fmt::print(stderr, "@odata.type field doesn't exist in:\n {}\n",
                   jsonDecoded.dump(4));
        return false;
    }

    auto schemaType = getSchemaType(jsonDecoded);
    if (schemaType == JsonPdrType::logEntry)
    {
        return processLogEntry(jsonDecoded);
    }
    if (schemaType == JsonPdrType::logService)
    {
        return processLogService(jsonDecoded);
    }
    return processOtherTypes(jsonDecoded);
}

JsonPdrType ExternalStorerFileInterface::getSchemaType(
    const nlohmann::json& jsonSchema) const
{
    auto logEntryFound =
        std::string(jsonSchema["@odata.type"]).find("LogEntry");
    if (logEntryFound != std::string::npos)
    {
        return JsonPdrType::logEntry;
    }

    auto logServiceFound =
        std::string(jsonSchema["@odata.type"]).find("LogService");
    if (logServiceFound != std::string::npos)
    {
        return JsonPdrType::logService;
    }

    return JsonPdrType::other;
}

bool ExternalStorerFileInterface::processLogEntry(nlohmann::json& logEntry)
{
    // TODO: Add policies for LogEntry retention.
    // https://github.com/openbmc/bios-bmc-smm-error-logger/issues/1.
    if (logServiceId.empty())
    {
        fmt::print(stderr, "First need a LogService PDR with a new UUID.\n");
        return false;
    }

    std::string id = boost::uuids::to_string(randomGen());
    std::string fullPath =
        fmt::format("{}/redfish/v1/Systems/system/LogServices/{}/Entries/{}",
                    rootPath, logServiceId, id);

    // Populate the "Id" with the UUID we generated.
    logEntry["Id"] = id;
    // Remove the @odata.id from the JSON since ExternalStorer will fill it for
    // a client.
    logEntry.erase("@odata.id");

    if (!fileHandler->createFile(fullPath, logEntry))
    {
        fmt::print(stderr, "Failed to create a file for log entry path: {}\n",
                   fullPath);
        return false;
    }

    cperNotifier->createEntry(fullPath + "/index.json");
    return true;
}

bool ExternalStorerFileInterface::processLogService(
    const nlohmann::json& logService)
{
    if (!logService.contains("@odata.id"))
    {
        fmt::print(stderr, "@odata.id field doesn't exist in:\n {}\n",
                   logService.dump(4));
        return false;
    }

    if (!logService.contains("Id"))
    {
        fmt::print(stderr, "Id field doesn't exist in:\n {}\n",
                   logService.dump(4));
        return false;
    }

    logServiceId = logService["Id"].get<std::string>();

    if (!createFile(logService["@odata.id"].get<std::string>(), logService))
    {
        fmt::print(stderr, "Failed to create LogService index file for:\n{}\n",
                   logService.dump(4));
        return false;
    }
    // ExternalStorer needs a .../Entries/index.json file with no data.
    nlohmann::json jEmpty = "{}"_json;
    return createFile(logService["@odata.id"].get<std::string>() + "/Entries",
                      jEmpty);
}

bool ExternalStorerFileInterface::processOtherTypes(
    const nlohmann::json& jsonPdr) const
{
    if (!jsonPdr.contains("@odata.id"))
    {
        fmt::print(stderr, "@odata.id field doesn't exist in:\n {}\n",
                   jsonPdr.dump(4));
        return false;
    }
    return createFile(jsonPdr["@odata.id"].get<std::string>(), jsonPdr);
}

bool ExternalStorerFileInterface::createFile(
    const std::string& subPath, const nlohmann::json& jsonPdr) const
{
    return fileHandler->createFile(rootPath + subPath, jsonPdr);
}

} // namespace rde
} // namespace bios_bmc_smm_error_logger
