#include "config.h"

#include "elog_serialize.hpp"

#include <cereal/archives/binary.hpp>
#include <cereal/types/map.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/tuple.hpp>
#include <cereal/types/vector.hpp>
#include <phosphor-logging/lg2.hpp>

#include <fstream>

// Register class version
// From cereal documentation;
// "This macro should be placed at global scope"
CEREAL_CLASS_VERSION(phosphor::logging::Entry, CLASS_VERSION)

namespace phosphor
{
namespace logging
{

/** @brief Function required by Cereal to perform serialization.
 *  @tparam Archive - Cereal archive type (binary in our case).
 *  @param[in] a       - reference to Cereal archive.
 *  @param[in] e       - const reference to error entry.
 *  @param[in] version - Class version that enables handling
 *                       a serialized data across code levels
 */
template <class Archive>
void save(Archive& a, const Entry& e, const std::uint32_t /*version*/)
{
    a(e.id(), e.severity(), e.timestamp(), e.message(), e.additionalData2(),
      e.associations(), e.resolved(), e.version(), e.updateTimestamp(),
      e.eventId(), e.resolution());
}

/** @brief Function required by Cereal to perform deserialization.
 *  @tparam Archive - Cereal archive type (binary in our case).
 *  @param[in] a       - reference to Cereal archive.
 *  @param[in] e       - reference to error entry.
 *  @param[in] version - Class version that enables handling
 *                       a serialized data across code levels
 */
template <class Archive>
void load(Archive& a, Entry& e, const std::uint32_t version)
{
    using namespace sdbusplus::server::xyz::openbmc_project::logging;

    uint32_t id{};
    Entry::Level severity{};
    uint64_t timestamp{};
    std::string message{};
    std::map<std::string, std::string> additionalData{};
    bool resolved{};
    AssociationList associations{};
    std::string fwVersion{};
    uint64_t updateTimestamp{};
    std::string eventId{};
    std::string resolution{};

    if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_FWLEVEL))
    {
        std::vector<std::string> additionalData_old{};
        a(id, severity, timestamp, message, additionalData_old, associations,
          resolved);
        updateTimestamp = timestamp;
        additionalData = util::additional_data::parse(additionalData_old);
    }
    else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_UPDATE_TS))
    {
        std::vector<std::string> additionalData_old{};
        a(id, severity, timestamp, message, additionalData_old, associations,
          resolved, fwVersion);
        updateTimestamp = timestamp;
        additionalData = util::additional_data::parse(additionalData_old);
    }
    else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_EVENTID))
    {
        std::vector<std::string> additionalData_old{};
        a(id, severity, timestamp, message, additionalData_old, associations,
          resolved, fwVersion, updateTimestamp);
        additionalData = util::additional_data::parse(additionalData_old);
    }
    else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_RESOLUTION))
    {
        std::vector<std::string> additionalData_old{};
        a(id, severity, timestamp, message, additionalData_old, associations,
          resolved, fwVersion, updateTimestamp, eventId);
        additionalData = util::additional_data::parse(additionalData_old);
    }
    else if (version <
             std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_METADATA_DICT))
    {
        std::vector<std::string> additionalData_old{};
        a(id, severity, timestamp, message, additionalData_old, associations,
          resolved, fwVersion, updateTimestamp, eventId, resolution);
        additionalData = util::additional_data::parse(additionalData_old);
    }
    else
    {
        a(id, severity, timestamp, message, additionalData, associations,
          resolved, fwVersion, updateTimestamp, eventId, resolution);
    }

    e.id(id, true);
    e.severity(severity, true);
    e.timestamp(timestamp, true);
    e.message(message, true);
    e.additionalData(util::additional_data::combine(additionalData), true);
    e.additionalData2(additionalData, true);
    e.sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved(
        resolved, true);
    e.associations(associations, true);
    e.version(fwVersion, true);
    e.purpose(sdbusplus::server::xyz::openbmc_project::software::Version::
                  VersionPurpose::BMC,
              true);
    e.updateTimestamp(updateTimestamp, true);
    e.eventId(eventId, true);
    e.resolution(resolution, true);
}

fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
{
    return dir / std::to_string(id);
}

fs::path serialize(const Entry& e, const fs::path& dir)
{
    auto path = getEntrySerializePath(e.id(), dir);
    std::ofstream os(path.c_str(), std::ios::binary);
    cereal::BinaryOutputArchive oarchive(os);
    oarchive(e);
    return path;
}

bool deserialize(const fs::path& path, Entry& e)
{
    try
    {
        if (fs::exists(path))
        {
            std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
            cereal::BinaryInputArchive iarchive(is);
            iarchive(e);
            return true;
        }
        return false;
    }
    catch (const cereal::Exception& ex)
    {
        lg2::error("{EXCEPTION}", "EXCEPTION", ex);
        fs::remove(path);
        return false;
    }
    catch (const std::length_error& ex)
    {
        // Running into: USCiLab/cereal#192
        // This may be indicating some other issue in the
        // way vector may have been used inside the logging.
        // possibly associations ??. But handling it here for
        // now since we are anyway tossing the log
        // TODO: openbmc/phosphor-logging#8
        lg2::error("{EXCEPTION}", "EXCEPTION", ex);
        fs::remove(path);
        return false;
    }
}

} // namespace logging
} // namespace phosphor
