#include "config.h"

#include "event_logger.hpp"

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

#include <systemd/sd-bus.h>

#include <utility/json_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;

        // 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)
                {
                    l_calloutInvPath = jsonUtility::getInventoryObjPathFromJson(
                        jsonUtility::getParsedJson(INVENTORY_JSON_SYM_LINK),
                        std::get<0>(i_callouts[0]));
                }
                else
                {
                    logging::logMessage(
                        "Error finding symlink. Continue with given path");
                }
            }
        }

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

        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("Eeprom 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
