#include "config.h"

#include "event_logger.hpp"

#include "exceptions.hpp"
#include "logger.hpp"

#include <systemd/sd-bus.h>

#include <utility/common_utility.hpp>
#include <utility/json_utility.hpp>
#include <utility/vpd_specific_utility.hpp>

#include <filesystem>

namespace vpd
{
const std::unordered_map<types::SeverityType, std::string>
    EventLogger::m_severityMap = {
        {types::SeverityType::Notice,
         "xyz.openbmc_project.Logging.Entry.Level.Notice"},
        {types::SeverityType::Informational,
         "xyz.openbmc_project.Logging.Entry.Level.Informational"},
        {types::SeverityType::Debug,
         "xyz.openbmc_project.Logging.Entry.Level.Debug"},
        {types::SeverityType::Warning,
         "xyz.openbmc_project.Logging.Entry.Level.Warning"},
        {types::SeverityType::Critical,
         "xyz.openbmc_project.Logging.Entry.Level.Critical"},
        {types::SeverityType::Emergency,
         "xyz.openbmc_project.Logging.Entry.Level.Emergency"},
        {types::SeverityType::Alert,
         "xyz.openbmc_project.Logging.Entry.Level.Alert"},
        {types::SeverityType::Error,
         "xyz.openbmc_project.Logging.Entry.Level.Error"}};

const std::unordered_map<types::ErrorType, std::string>
    EventLogger::m_errorMsgMap = {
        {types::ErrorType::DefaultValue, "com.ibm.VPD.Error.DefaultValue"},
        {types::ErrorType::UndefinedError, "com.ibm.VPD.Error.UndefinedError"},
        {types::ErrorType::InvalidVpdMessage, "com.ibm.VPD.Error.InvalidVPD"},
        {types::ErrorType::VpdMismatch, "com.ibm.VPD.Error.Mismatch"},
        {types::ErrorType::InvalidEeprom,
         "com.ibm.VPD.Error.InvalidEepromPath"},
        {types::ErrorType::EccCheckFailed, "com.ibm.VPD.Error.EccCheckFailed"},
        {types::ErrorType::JsonFailure, "com.ibm.VPD.Error.InvalidJson"},
        {types::ErrorType::DbusFailure, "com.ibm.VPD.Error.DbusFailure"},
        {types::ErrorType::InvalidSystem,
         "com.ibm.VPD.Error.UnknownSystemType"},
        {types::ErrorType::EssentialFru,
         "com.ibm.VPD.Error.RequiredFRUMissing"},
        {types::ErrorType::GpioError, "com.ibm.VPD.Error.GPIOError"},
        {types::ErrorType::InternalFailure,
         "xyz.openbmc_project.Common.Error.InternalFailure"},
        {types::ErrorType::FruMissing, "com.ibm.VPD.Error.RequiredFRUMissing"},
        {types::ErrorType::SystemTypeMismatch,
         "com.ibm.VPD.Error.SystemTypeMismatch"},
        {types::ErrorType::UnknownSystemSettings,
         "com.ibm.VPD.Error.UnknownSystemSettings"},
        {types::ErrorType::FirmwareError, "com.ibm.VPD.Error.FirmwareError"},
        {types::ErrorType::VpdParseError, "com.ibm.VPD.Error.VPDParseError"}};

const std::unordered_map<types::CalloutPriority, std::string>
    EventLogger::m_priorityMap = {
        {types::CalloutPriority::High, "H"},
        {types::CalloutPriority::Medium, "M"},
        {types::CalloutPriority::MediumGroupA, "A"},
        {types::CalloutPriority::MediumGroupB, "B"},
        {types::CalloutPriority::MediumGroupC, "C"},
        {types::CalloutPriority::Low, "L"}};

void EventLogger::createAsyncPelWithInventoryCallout(
    const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
    const std::vector<types::InventoryCalloutData>& i_callouts,
    const std::string& i_fileName, const std::string& i_funcName,
    const uint8_t i_internalRc, const std::string& i_description,
    const std::optional<std::string> i_userData1,
    const std::optional<std::string> i_userData2,
    const std::optional<std::string> i_symFru,
    const std::optional<std::string> i_procedure)
{
    (void)i_symFru;
    (void)i_procedure;

    try
    {
        if (i_callouts.empty())
        {
            logging::logMessage("Callout information is missing to create PEL");
            // TODO: Revisit this instead of simpley returning.
            return;
        }

        if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
        {
            throw std::runtime_error(
                "Error type not found in the error message map to create PEL");
            // TODO: Need to handle, instead of throwing exception. Create
            // default message in message_registry.json.
        }

        const std::string& l_message = m_errorMsgMap.at(i_errorType);

        const std::string& l_severity =
            (m_severityMap.find(i_severity) != m_severityMap.end()
                 ? m_severityMap.at(i_severity)
                 : m_severityMap.at(types::SeverityType::Informational));

        std::string l_description =
            (!i_description.empty() ? i_description : "VPD generic error");

        std::string l_userData1 = (i_userData1) ? (*i_userData1) : "";

        std::string l_userData2 = (i_userData2) ? (*i_userData2) : "";

        const types::InventoryCalloutData& l_invCallout = i_callouts[0];
        // TODO: Need to handle multiple inventory path callout's, when multiple
        // callout's is supported by "Logging" service.

        const types::CalloutPriority& l_priorityEnum = get<1>(l_invCallout);

        const std::string& l_priority =
            (m_priorityMap.find(l_priorityEnum) != m_priorityMap.end()
                 ? m_priorityMap.at(l_priorityEnum)
                 : m_priorityMap.at(types::CalloutPriority::Low));

        sd_bus* l_sdBus = nullptr;
        sd_bus_default(&l_sdBus);

        const uint8_t l_additionalDataCount = 8;
        auto l_rc = sd_bus_call_method_async(
            l_sdBus, NULL, constants::eventLoggingServiceName,
            constants::eventLoggingObjectPath, constants::eventLoggingInterface,
            "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
            l_severity.c_str(), l_additionalDataCount, "FileName",
            i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
            "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
            l_description.c_str(), "UserData1", l_userData1.c_str(),
            "UserData2", l_userData2.c_str(), "CALLOUT_INVENTORY_PATH",
            get<0>(l_invCallout).c_str(), "CALLOUT_PRIORITY",
            l_priority.c_str());

        if (l_rc < 0)
        {
            logging::logMessage(
                "Error calling sd_bus_call_method_async, Message = " +
                std::string(strerror(-l_rc)));
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Create PEL failed with error: " + std::string(l_ex.what()));
    }
}

void EventLogger::createAsyncPelWithI2cDeviceCallout(
    const types::ErrorType i_errorType, const types::SeverityType i_severity,
    const std::vector<types::DeviceCalloutData>& i_callouts,
    const std::string& i_fileName, const std::string& i_funcName,
    const uint8_t i_internalRc,
    const std::optional<std::pair<std::string, std::string>> i_userData1,
    const std::optional<std::pair<std::string, std::string>> i_userData2)
{
    // TODO, implementation needs to be added.
    (void)i_errorType;
    (void)i_severity;
    (void)i_callouts;
    (void)i_fileName;
    (void)i_funcName;
    (void)i_internalRc;
    (void)i_userData1;
    (void)i_userData2;
}

void EventLogger::createAsyncPelWithI2cBusCallout(
    const types::ErrorType i_errorType, const types::SeverityType i_severity,
    const std::vector<types::I2cBusCalloutData>& i_callouts,
    const std::string& i_fileName, const std::string& i_funcName,
    const uint8_t i_internalRc,
    const std::optional<std::pair<std::string, std::string>> i_userData1,
    const std::optional<std::pair<std::string, std::string>> i_userData2)
{
    // TODO, implementation needs to be added.
    (void)i_errorType;
    (void)i_severity;
    (void)i_callouts;
    (void)i_fileName;
    (void)i_funcName;
    (void)i_internalRc;
    (void)i_userData1;
    (void)i_userData2;
}

void EventLogger::createAsyncPel(
    const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
    const std::string& i_fileName, const std::string& i_funcName,
    const uint8_t i_internalRc, const std::string& i_description,
    const std::optional<std::string> i_userData1,
    const std::optional<std::string> i_userData2,
    const std::optional<std::string> i_symFru,
    const std::optional<std::string> i_procedure)
{
    (void)i_symFru;
    (void)i_procedure;
    try
    {
        if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
        {
            throw std::runtime_error("Unsupported error type received");
            // TODO: Need to handle, instead of throwing an exception.
        }

        const std::string& l_message = m_errorMsgMap.at(i_errorType);

        const std::string& l_severity =
            (m_severityMap.find(i_severity) != m_severityMap.end()
                 ? m_severityMap.at(i_severity)
                 : m_severityMap.at(types::SeverityType::Informational));

        const std::string l_description =
            ((!i_description.empty() ? i_description : "VPD generic error"));

        const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");

        const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");

        sd_bus* l_sdBus = nullptr;
        sd_bus_default(&l_sdBus);

        // VALUE_6 represents the additional data pair count passing to create
        // PEL. If there any change in additional data, we need to pass the
        // correct number.
        auto l_rc = sd_bus_call_method_async(
            l_sdBus, NULL, constants::eventLoggingServiceName,
            constants::eventLoggingObjectPath, constants::eventLoggingInterface,
            "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
            l_severity.c_str(), constants::VALUE_6, "FileName",
            i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
            "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
            l_description.c_str(), "UserData1", l_userData1.c_str(),
            "UserData2", l_userData2.c_str());

        if (l_rc < 0)
        {
            logging::logMessage(
                "Error calling sd_bus_call_method_async, Message = " +
                std::string(strerror(-l_rc)));
        }
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage("Async PEL creation failed with an error: " +
                            std::string(l_ex.what()));
    }
}

void EventLogger::createSyncPel(
    const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
    const std::string& i_fileName, const std::string& i_funcName,
    const uint8_t i_internalRc, const std::string& i_description,
    const std::optional<std::string> i_userData1,
    const std::optional<std::string> i_userData2,
    const std::optional<std::string> i_symFru,
    const std::optional<std::string> i_procedure)
{
    (void)i_symFru;
    (void)i_procedure;
    try
    {
        if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
        {
            throw std::runtime_error("Unsupported error type received");
            // TODO: Need to handle, instead of throwing an exception.
        }

        const std::string& l_message = m_errorMsgMap.at(i_errorType);

        const std::string& l_severity =
            (m_severityMap.find(i_severity) != m_severityMap.end()
                 ? m_severityMap.at(i_severity)
                 : m_severityMap.at(types::SeverityType::Informational));

        const std::string l_description =
            ((!i_description.empty() ? i_description : "VPD generic error"));

        const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");

        const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");

        std::map<std::string, std::string> l_additionalData{
            {"FileName", i_fileName},
            {"FunctionName", i_funcName},
            {"DESCRIPTION", l_description},
            {"InteranlRc", std::to_string(i_internalRc)},
            {"UserData1", l_userData1.c_str()},
            {"UserData2", l_userData2.c_str()}};

        auto l_bus = sdbusplus::bus::new_default();
        auto l_method =
            l_bus.new_method_call(constants::eventLoggingServiceName,
                                  constants::eventLoggingObjectPath,
                                  constants::eventLoggingInterface, "Create");
        l_method.append(l_message, l_severity, l_additionalData);
        l_bus.call(l_method);
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage("Sync PEL creation failed with an error: " +
                            std::string(l_ex.what()));
    }
}

void EventLogger::createSyncPelWithInvCallOut(
    const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
    const std::string& i_fileName, const std::string& i_funcName,
    const uint8_t i_internalRc, const std::string& i_description,
    const std::vector<types::InventoryCalloutData>& i_callouts,
    const std::optional<std::string> i_userData1,
    const std::optional<std::string> i_userData2,
    [[maybe_unused]] const std::optional<std::string> i_symFru,
    [[maybe_unused]] const std::optional<std::string> i_procedure)
{
    try
    {
        if (i_callouts.empty())
        {
            createSyncPel(i_errorType, i_severity, i_fileName, i_funcName,
                          i_internalRc, i_description, i_userData1, i_userData2,
                          i_symFru, i_procedure);
            logging::logMessage(
                "Callout list is empty, creating PEL without call out");
            return;
        }

        if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
        {
            throw std::runtime_error("Unsupported error type received");
        }

        // Path to hold callout inventory path.
        std::string l_calloutInvPath;

        uint16_t l_errCode = 0;

        // check if callout path is a valid inventory path. if not, get the JSON
        // object to get inventory path.
        if (std::get<0>(i_callouts[0])
                .compare(constants::VALUE_0, strlen(constants::pimPath),
                         constants::pimPath) != constants::STR_CMP_SUCCESS)
        {
            std::error_code l_ec;
            // implies json dependent execution.
            if (std::filesystem::exists(INVENTORY_JSON_SYM_LINK, l_ec))
            {
                if (!l_ec)
                {
                    nlohmann::json l_parsedJson = jsonUtility::getParsedJson(
                        INVENTORY_JSON_SYM_LINK, l_errCode);

                    if (l_errCode)
                    {
                        logging::logMessage(
                            "Failed to parse JSON file [ " +
                            std::string(INVENTORY_JSON_SYM_LINK) +
                            " ], error : " +
                            commonUtility::getErrCodeMsg(l_errCode));
                    }

                    l_calloutInvPath = jsonUtility::getInventoryObjPathFromJson(
                        l_parsedJson, std::get<0>(i_callouts[0]), l_errCode);
                }
                else
                {
                    logging::logMessage(
                        "Error finding symlink. Continue with given path");
                }
            }
        }

        if (l_calloutInvPath.empty())
        {
            l_calloutInvPath = std::get<0>(i_callouts[0]);

            if (l_errCode)
            {
                logging::logMessage(
                    "Failed to get inventory object path from JSON for FRU [" +
                    std::get<0>(i_callouts[0]) +
                    "], error : " + commonUtility::getErrCodeMsg(l_errCode));
            }
        }

        const std::map<std::string, std::string> l_additionalData{
            {"FileName", i_fileName},
            {"FunctionName", i_funcName},
            {"DESCRIPTION",
             (!i_description.empty() ? i_description : "VPD generic error")},
            {"CALLOUT_INVENTORY_PATH", l_calloutInvPath},
            {"InteranlRc", std::to_string(i_internalRc)},
            {"UserData1", ((i_userData1) ? (*i_userData1) : "").c_str()},
            {"UserData2", ((i_userData2) ? (*i_userData2) : "").c_str()}};

        const std::string& l_severity =
            (m_severityMap.find(i_severity) != m_severityMap.end()
                 ? m_severityMap.at(i_severity)
                 : m_severityMap.at(types::SeverityType::Informational));

        auto l_bus = sdbusplus::bus::new_default();
        auto l_method =
            l_bus.new_method_call(constants::eventLoggingServiceName,
                                  constants::eventLoggingObjectPath,
                                  constants::eventLoggingInterface, "Create");
        l_method.append(m_errorMsgMap.at(i_errorType), l_severity,
                        l_additionalData);
        l_bus.call(l_method);
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Sync PEL creation with inventory path failed with error: " +
            std::string(l_ex.what()));
    }
}

types::ExceptionDataMap EventLogger::getExceptionData(
    const std::exception& i_exception)
{
    types::ExceptionDataMap l_errorInfo{
        {"ErrorType", types::ErrorType::UndefinedError},
        {"ErrorMsg", i_exception.what()}};

    try
    {
        if (typeid(i_exception) == typeid(DataException))
        {
            const DataException& l_ex =
                dynamic_cast<const DataException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Data Exception. Reason: ") + i_exception.what();
        }
        else if (typeid(i_exception) == typeid(EccException))
        {
            const EccException& l_ex =
                dynamic_cast<const EccException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Ecc Exception. Reason: ") + i_exception.what();
        }
        else if (typeid(i_exception) == typeid(JsonException))
        {
            const JsonException& l_ex =
                dynamic_cast<const JsonException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Json Exception. Reason: ") + i_exception.what();
        }
        else if (typeid(i_exception) == typeid(GpioException))
        {
            const GpioException& l_ex =
                dynamic_cast<const GpioException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Gpio Exception. Reason: ") + i_exception.what();
        }
        else if (typeid(i_exception) == typeid(DbusException))
        {
            const DbusException& l_ex =
                dynamic_cast<const DbusException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Dbus Exception. Reason: ") + i_exception.what();
        }
        else if (typeid(i_exception) == typeid(FirmwareException))
        {
            const FirmwareException& l_ex =
                dynamic_cast<const FirmwareException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Firmware Exception. Reason: ") +
                i_exception.what();
        }
        else if (typeid(i_exception) == typeid(EepromException))
        {
            const EepromException& l_ex =
                dynamic_cast<const EepromException&>(i_exception);
            l_errorInfo["ErrorType"] = l_ex.getErrorType();
            l_errorInfo["ErrorMsg"] =
                std::string("Eeprom Exception. Reason: ") + i_exception.what();
        }
        else if (typeid(i_exception) == typeid(std::runtime_error))
        {
            // Since it is a standard exception no casting is required and error
            // type is hardcoded.
            l_errorInfo["ErrorType"] = types::ErrorType::FirmwareError;
            l_errorInfo["ErrorMsg"] =
                std::string("Standard runtime exception. Reason: ") +
                i_exception.what();
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Failed to get error info, reason: " + std::string(l_ex.what()));
    }
    return l_errorInfo;
}

types::ErrorType EventLogger::getErrorType(const std::exception& i_exception)
{
    const auto& l_exceptionDataMap = getExceptionData(i_exception);

    auto l_itrToErrType = l_exceptionDataMap.find("ErrorType");
    if (l_itrToErrType == l_exceptionDataMap.end())
    {
        return types::ErrorType::UndefinedError;
    }

    auto l_ptrToErrType =
        std::get_if<types::ErrorType>(&l_itrToErrType->second);
    if (!l_ptrToErrType)
    {
        return types::ErrorType::UndefinedError;
    }

    return *l_ptrToErrType;
}

std::string EventLogger::getErrorMsg(const std::exception& i_exception)
{
    const auto& l_exceptionDataMap = getExceptionData(i_exception);

    auto l_itrToErrMsg = l_exceptionDataMap.find("ErrorMsg");
    if (l_itrToErrMsg == l_exceptionDataMap.end())
    {
        return i_exception.what();
    }

    auto l_ptrToErrMsg = std::get_if<std::string>(&l_itrToErrMsg->second);
    if (!l_ptrToErrMsg)
    {
        return i_exception.what();
    }

    return *l_ptrToErrMsg;
}

std::string EventLogger::getErrorTypeString(
    const types::ErrorType& i_errorType) noexcept
{
    const auto l_entry = m_errorMsgMap.find(i_errorType);
    return (l_entry != m_errorMsgMap.end()
                ? l_entry->second
                : m_errorMsgMap.at(types::ErrorType::UndefinedError));
}
} // namespace vpd
