#include "event_manager.hpp"

#include "terminus_manager.hpp"

#include <libpldm/edac.h>
#include <libpldm/platform.h>

#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/Dump/Create/common.hpp>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>

#include <cerrno>
#include <memory>

PHOSPHOR_LOG2_USING;

using DumpCreate = sdbusplus::common::xyz::openbmc_project::dump::Create;

namespace pldm
{
namespace platform_mc
{
int EventManager::handlePlatformEvent(
    pldm_tid_t tid, uint16_t eventId, uint8_t eventClass,
    const uint8_t* eventData, size_t eventDataSize)
{
    /* Only handle the event of the discovered termini*/
    if (!termini.contains(tid))
    {
        return PLDM_SUCCESS;
    }
    /* EventClass sensorEvent `Table 11 - PLDM Event Types` DSP0248 */
    if (eventClass == PLDM_SENSOR_EVENT)
    {
        uint16_t sensorId = 0;
        uint8_t sensorEventClassType = 0;
        size_t eventClassDataOffset = 0;
        auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
                                           &sensorEventClassType,
                                           &eventClassDataOffset);
        if (rc)
        {
            lg2::error(
                "Failed to decode sensor event data from terminus ID {TID}, event class {CLASS}, event ID {EVENTID} with return code {RC}.",
                "TID", tid, "CLASS", eventClass, "EVENTID", eventId, "RC", rc);
            return rc;
        }
        switch (sensorEventClassType)
        {
            case PLDM_NUMERIC_SENSOR_STATE:
            {
                const uint8_t* sensorData = eventData + eventClassDataOffset;
                size_t sensorDataLength = eventDataSize - eventClassDataOffset;
                return processNumericSensorEvent(tid, sensorId, sensorData,
                                                 sensorDataLength);
            }
            case PLDM_STATE_SENSOR_STATE:
            case PLDM_SENSOR_OP_STATE:
            default:
                lg2::info(
                    "Unsupported class type {CLASSTYPE} for the sensor event from terminus ID {TID} sensorId {SID}",
                    "CLASSTYPE", sensorEventClassType, "TID", tid, "SID",
                    sensorId);
                return PLDM_ERROR;
        }
    }

    /* EventClass CPEREvent as `Table 11 - PLDM Event Types` DSP0248 V1.3.0 */
    if (eventClass == PLDM_CPER_EVENT)
    {
        return processCperEvent(tid, eventId, eventData, eventDataSize);
    }

    /* EventClass pldmMessagePollEvent `Table 11 - PLDM Event Types` DSP0248 */
    if (eventClass == PLDM_MESSAGE_POLL_EVENT)
    {
        lg2::info("Received pldmMessagePollEvent for terminus {TID}", "TID",
                  tid);
        pldm_message_poll_event poll_event{};
        auto rc = decode_pldm_message_poll_event_data(eventData, eventDataSize,
                                                      &poll_event);
        if (rc)
        {
            lg2::error(
                "Failed to decode PldmMessagePollEvent event, error {RC} ",
                "RC", rc);
            return rc;
        }

        auto it = termini.find(tid);
        if (it != termini.end())
        {
            auto& terminus = it->second; // Reference for clarity
            terminus->pollEvent = true;
            terminus->pollEventId = poll_event.event_id;
            terminus->pollDataTransferHandle = poll_event.data_transfer_handle;
        }

        return PLDM_SUCCESS;
    }

    lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE", eventClass);

    return PLDM_ERROR;
}

int triggerNumericSensorThresholdEvent(NumericSensorThresholdHandler handler,
                                       uint8_t previousEventState,
                                       uint8_t nextEventState, double value)
{
    static const std::map<
        uint8_t, std::tuple<pldm::utils::Level, pldm::utils::Direction>>
        sensorEventMap = {
            {PLDM_SENSOR_UPPERFATAL,
             {pldm::utils::Level::HARDSHUTDOWN, pldm::utils::Direction::HIGH}},
            {PLDM_SENSOR_UPPERCRITICAL,
             {pldm::utils::Level::CRITICAL, pldm::utils::Direction::HIGH}},
            {PLDM_SENSOR_UPPERWARNING,
             {pldm::utils::Level::WARNING, pldm::utils::Direction::HIGH}},
            {PLDM_SENSOR_LOWERWARNING,
             {pldm::utils::Level::WARNING, pldm::utils::Direction::LOW}},
            {PLDM_SENSOR_LOWERCRITICAL,
             {pldm::utils::Level::CRITICAL, pldm::utils::Direction::LOW}},
            {PLDM_SENSOR_LOWERFATAL,
             {pldm::utils::Level::HARDSHUTDOWN, pldm::utils::Direction::LOW}},
        };
    static const std::array<uint8_t, 7> stateOrder = {
        PLDM_SENSOR_LOWERFATAL,   PLDM_SENSOR_LOWERCRITICAL,
        PLDM_SENSOR_LOWERWARNING, PLDM_SENSOR_NORMAL,
        PLDM_SENSOR_UPPERWARNING, PLDM_SENSOR_UPPERCRITICAL,
        PLDM_SENSOR_UPPERFATAL};
    constexpr auto normalIt = stateOrder.begin() + 3;
    const auto normalState = *normalIt;
    auto prevIt =
        std::find(stateOrder.begin(), stateOrder.end(), previousEventState);
    if (prevIt == stateOrder.end())
    {
        lg2::error("Undefined previous threshold event state: {EVENT}", "EVENT",
                   previousEventState);
        return PLDM_ERROR;
    }
    auto nextIt =
        std::find(stateOrder.begin(), stateOrder.end(), nextEventState);
    if (nextIt == stateOrder.end())
    {
        lg2::error("Undefined current threshold event state: {EVENT}", "EVENT",
                   nextEventState);
        return PLDM_ERROR;
    }
    if (prevIt == nextIt)
    {
        // Nothing to do. Return success early
        return PLDM_SUCCESS;
    }

    // This is a rare condition. But if we are going wildy across the thresholds
    // crossing PLDM_SENSOR_NORMAL (Example going from PLDM_SENSOR_LOWERFATAL to
    // PLDM_SENSOR_UPPERFATAL in one event, then split it up into two)
    if ((prevIt < normalIt && nextIt > normalIt) ||
        (prevIt > normalIt && nextIt < normalIt))
    {
        int rc = triggerNumericSensorThresholdEvent(handler, *prevIt,
                                                    normalState, value);
        if (rc != PLDM_SUCCESS)
        {
            lg2::error("Error handling {PREV} to current for numeric sensor",
                       "PREV", int(*prevIt));
            return rc;
        }
        return triggerNumericSensorThresholdEvent(handler, normalState, *nextIt,
                                                  value);
    }
    bool goingUp = prevIt < nextIt;
    bool gettingBetter = (prevIt < nextIt && prevIt < normalIt) ||
                         (prevIt > nextIt && prevIt > normalIt);

    for (auto currIt = prevIt; currIt != nextIt; goingUp ? ++currIt : --currIt)
    {
        if (currIt == normalIt)
        {
            continue;
        }
        const auto& event = sensorEventMap.at(*currIt);

        if (gettingBetter)
        {
            if (currIt != prevIt)
            {
                // Just trigger an event in case it was missed before
                // we deassert. The implementation of triggerThresholdEvent
                // should just no-op if it is already triggered.
                handler(std::get<0>(event), std::get<1>(event), value, true,
                        true);
            }
            handler(std::get<0>(event), std::get<1>(event), value, false,
                    false);
        }
        else
        {
            handler(std::get<0>(event), std::get<1>(event), value, true, true);
        }
    }
    if (nextIt != normalIt)
    {
        const auto& event = sensorEventMap.at(*nextIt);
        return handler(std::get<0>(event), std::get<1>(event), value, true,
                       true);
    }
    return PLDM_SUCCESS;
}

int EventManager::processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
                                            const uint8_t* sensorData,
                                            size_t sensorDataLength)
{
    uint8_t eventState = 0;
    uint8_t previousEventState = 0;
    uint8_t sensorDataSize = 0;
    uint32_t presentReading = 0;
    auto rc = decode_numeric_sensor_data(
        sensorData, sensorDataLength, &eventState, &previousEventState,
        &sensorDataSize, &presentReading);
    if (rc)
    {
        lg2::error(
            "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ",
            "TID", tid, "RC", rc);
        return rc;
    }

    double value = static_cast<double>(presentReading);
    lg2::error(
        "processNumericSensorEvent tid {TID}, sensorID {SID} value {VAL} previousState {PSTATE} eventState {ESTATE}",
        "TID", tid, "SID", sensorId, "VAL", value, "PSTATE", previousEventState,
        "ESTATE", eventState);

    if (!termini.contains(tid) || !termini[tid])
    {
        lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
                   tid);
        return PLDM_ERROR;
    }

    auto& terminus = termini[tid];

    auto sensor = terminus->getSensorObject(sensorId);
    if (!sensor)
    {
        lg2::error(
            "Terminus ID {TID} has no sensor object with sensor ID {SID}.",
            "TID", tid, "SID", sensorId);
        return PLDM_ERROR;
    }
    auto sensorHandler =
        [&sensor](pldm::utils::Level level, pldm::utils::Direction direction,
                  double rawValue, bool newAlarm, bool assert) {
            return sensor->triggerThresholdEvent(level, direction, rawValue,
                                                 newAlarm, assert);
        };
    rc = triggerNumericSensorThresholdEvent(sensorHandler, previousEventState,
                                            eventState, value);
    if (rc)
    {
        lg2::error(
            "Terminus ID {TID} sensor {SID} threshold handling had errors",
            "TID", tid, "SID", sensorId);
        return rc;
    }
    return PLDM_SUCCESS;
}

int EventManager::processCperEvent(pldm_tid_t tid, uint16_t eventId,
                                   const uint8_t* eventData,
                                   const size_t eventDataSize)
{
    if (eventDataSize < PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH)
    {
        lg2::error(
            "Error : Invalid CPER Event data length for eventId {EVENTID}.",
            "EVENTID", eventId);
        return PLDM_ERROR;
    }
    const size_t cperEventDataSize =
        eventDataSize - PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH;
    const size_t msgDataLen =
        sizeof(pldm_platform_cper_event) + cperEventDataSize;
    std::string terminusName = "";
    auto msgData = std::make_unique<unsigned char[]>(msgDataLen);
    auto cperEvent = new (msgData.get()) pldm_platform_cper_event;

    auto rc = decode_pldm_platform_cper_event(eventData, eventDataSize,
                                              cperEvent, msgDataLen);

    if (rc)
    {
        lg2::error(
            "Failed to decode CPER event for eventId {EVENTID} of terminus ID {TID} error {RC}.",
            "EVENTID", eventId, "TID", tid, "RC", rc);
        return rc;
    }

    if (termini.contains(tid) && termini[tid])
    {
        auto tmp = termini[tid]->getTerminusName();
        if (tmp && !tmp.value().empty())
        {
            terminusName = static_cast<std::string>(tmp.value());
        }
    }
    else
    {
        lg2::error("Terminus ID {TID} is not in the managing list.", "TID",
                   tid);
        return PLDM_ERROR;
    }

    // Save event data to file
    std::filesystem::path dirName{"/var/cper"};
    if (!std::filesystem::exists(dirName))
    {
        try
        {
            std::filesystem::create_directory(dirName);
        }
        catch (const std::filesystem::filesystem_error& e)
        {
            lg2::error("Failed to create /var/cper directory: {ERROR}", "ERROR",
                       e);
            return PLDM_ERROR;
        }
    }

    std::string fileName{dirName.string() + "/cper-XXXXXX"};
    auto fd = mkstemp(fileName.data());
    if (fd < 0)
    {
        lg2::error("Failed to generate temp file, error {ERRORNO}", "ERRORNO",
                   std::strerror(errno));
        return PLDM_ERROR;
    }
    close(fd);

    std::ofstream ofs;
    ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit |
                   std::ofstream::eofbit);

    try
    {
        ofs.open(fileName);
        ofs.write(reinterpret_cast<const char*>(
                      pldm_platform_cper_event_event_data(cperEvent)),
                  cperEvent->event_data_length);
        ofs.close();

        if (cperEvent->format_type == PLDM_PLATFORM_CPER_EVENT_WITH_HEADER)
        {
            rc = createCperDumpEntry("CPER", fileName, terminusName);
        }
        else
        {
            rc = createCperDumpEntry("CPERSection", fileName, terminusName);
        }
    }
    catch (const std::ofstream::failure& e)
    {
        lg2::error("Failed to save CPER to '{FILENAME}', error - {ERROR}.",
                   "FILENAME", fileName, "ERROR", e);
        return PLDM_ERROR;
    }
    return rc;
}

int EventManager::createCperDumpEntry(const std::string& dataType,
                                      const std::string& dataPath,
                                      const std::string& typeName)
{
    auto createDump =
        [](std::map<std::string, std::variant<std::string, uint64_t>>&
               addData) {
            static constexpr auto dumpObjPath =
                "/xyz/openbmc_project/dump/faultlog";
            auto& bus = pldm::utils::DBusHandler::getBus();

            try
            {
                auto service = pldm::utils::DBusHandler().getService(
                    dumpObjPath, DumpCreate::interface);
                auto method = bus.new_method_call(
                    service.c_str(), dumpObjPath, DumpCreate::interface,
                    DumpCreate::method_names::create_dump);
                method.append(addData);
                bus.call_noreply(method);
            }
            catch (const std::exception& e)
            {
                lg2::error(
                    "Failed to create D-Bus Dump entry, error - {ERROR}.",
                    "ERROR", e);
            }
        };

    std::map<std::string, std::variant<std::string, uint64_t>> addData;
    addData["Type"] = dataType;
    addData["PrimaryLogId"] = dataPath;
    addData["AdditionalTypeName"] = typeName;
    createDump(addData);
    return PLDM_SUCCESS;
}

int EventManager::getNextPartParameters(
    uint16_t eventId, std::vector<uint8_t> eventMessage, uint8_t transferFlag,
    uint32_t eventDataIntegrityChecksum, uint32_t nextDataTransferHandle,
    uint8_t* transferOperationFlag, uint32_t* dataTransferHandle,
    uint32_t* eventIdToAcknowledge)
{
    if (transferFlag != PLDM_PLATFORM_TRANSFER_START_AND_END &&
        transferFlag != PLDM_PLATFORM_TRANSFER_END)
    {
        *transferOperationFlag = PLDM_GET_NEXTPART;
        *dataTransferHandle = nextDataTransferHandle;
        *eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_FRAGMENT;
        return PLDM_SUCCESS;
    }

    if (transferFlag == PLDM_PLATFORM_TRANSFER_END)
    {
        if (eventDataIntegrityChecksum !=
            pldm_edac_crc32(eventMessage.data(), eventMessage.size()))
        {
            lg2::error("pollForPlatformEventMessage invalid checksum.");
            return PLDM_ERROR_INVALID_DATA;
        }
    }

    /* End of one event. Set request transfer flag to ACK */
    *transferOperationFlag = PLDM_ACKNOWLEDGEMENT_ONLY;
    *dataTransferHandle = 0;
    *eventIdToAcknowledge = eventId;

    return PLDM_SUCCESS;
}

void EventManager::callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass,
                                           uint16_t eventId,
                                           std::vector<uint8_t>& eventMessage)
{
    try
    {
        const auto& handlers = eventHandlers.at(eventClass);
        for (const auto& handler : handlers)
        {
            auto rc =
                handler(tid, eventId, eventMessage.data(), eventMessage.size());
            if (rc != PLDM_SUCCESS)
            {
                lg2::error(
                    "Failed to handle platform event msg for terminus {TID}, event {EVENTID} return {RET}",
                    "TID", tid, "EVENTID", eventId, "RET", rc);
            }
        }
    }
    catch (const std::out_of_range& e)
    {
        lg2::error(
            "Failed to handle platform event msg for terminus {TID}, event {EVENTID} error - {ERROR}",
            "TID", tid, "EVENTID", eventId, "ERROR", e);
    }
}

exec::task<int> EventManager::pollForPlatformEventTask(
    pldm_tid_t tid, uint32_t pollDataTransferHandle)
{
    uint8_t rc = 0;
    // Set once, doesn't need resetting
    uint8_t transferOperationFlag = PLDM_GET_FIRSTPART;
    uint32_t dataTransferHandle = pollDataTransferHandle;
    uint32_t eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NULL;
    uint8_t formatVersion = 0x1; // Constant, no need to reset
    uint16_t eventId = PLDM_PLATFORM_EVENT_ID_ACK;
    uint16_t polledEventId = PLDM_PLATFORM_EVENT_ID_NONE;
    pldm_tid_t polledEventTid = 0;
    uint8_t polledEventClass = 0;

    std::vector<uint8_t> eventMessage{};

    // Reset and mark terminus as available
    updateAvailableState(tid, true);

    while (eventId != PLDM_PLATFORM_EVENT_ID_NONE)
    {
        uint8_t completionCode = 0;
        pldm_tid_t eventTid = PLDM_PLATFORM_EVENT_ID_NONE;
        eventId = PLDM_PLATFORM_EVENT_ID_NONE;
        uint32_t nextDataTransferHandle = 0;
        uint8_t transferFlag = 0;
        uint8_t eventClass = 0;
        uint32_t eventDataSize = 0;
        uint8_t* eventData = nullptr;
        uint32_t eventDataIntegrityChecksum = 0;

        /* Stop event polling */
        if (!getAvailableState(tid))
        {
            lg2::info(
                "Terminus ID {TID} is not available for PLDM request from {NOW}.",
                "TID", tid, "NOW", pldm::utils::getCurrentSystemTime());
            co_await stdexec::just_stopped();
        }

        rc = co_await pollForPlatformEventMessage(
            tid, formatVersion, transferOperationFlag, dataTransferHandle,
            eventIdToAcknowledge, completionCode, eventTid, eventId,
            nextDataTransferHandle, transferFlag, eventClass, eventDataSize,
            eventData, eventDataIntegrityChecksum);
        if (rc || completionCode != PLDM_SUCCESS)
        {
            lg2::error(
                "Failed to pollForPlatformEventMessage for terminus {TID}, event {EVENTID}, error {RC}, complete code {CC}",
                "TID", tid, "EVENTID", eventId, "RC", rc, "CC", completionCode);
            co_return rc;
        }

        if (eventDataSize > 0)
        {
            eventMessage.insert(eventMessage.end(), eventData,
                                eventData + eventDataSize);
        }

        if (transferOperationFlag == PLDM_ACKNOWLEDGEMENT_ONLY)
        {
            /* Handle the polled event after finish ACK it */
            if (eventHandlers.contains(polledEventClass))
            {
                callPolledEventHandlers(polledEventTid, polledEventClass,
                                        polledEventId, eventMessage);
            }
            eventMessage.clear();

            if (eventId == PLDM_PLATFORM_EVENT_ID_ACK)
            {
                transferOperationFlag = PLDM_GET_FIRSTPART;
                dataTransferHandle = 0;
                eventIdToAcknowledge = PLDM_PLATFORM_EVENT_ID_NULL;
            }
        }
        else
        {
            auto ret = getNextPartParameters(
                eventId, eventMessage, transferFlag, eventDataIntegrityChecksum,
                nextDataTransferHandle, &transferOperationFlag,
                &dataTransferHandle, &eventIdToAcknowledge);
            if (ret)
            {
                lg2::error(
                    "Failed to process data of pollForPlatformEventMessage for terminus {TID}, event {EVENTID} return {RET}",
                    "TID", tid, "EVENTID", eventId, "RET", ret);
                co_return PLDM_ERROR_INVALID_DATA;
            }

            /* Store the polled event INFO to handle after ACK */
            if ((transferFlag == PLDM_PLATFORM_TRANSFER_START_AND_END) ||
                (transferFlag == PLDM_PLATFORM_TRANSFER_END))
            {
                polledEventTid = eventTid;
                polledEventId = eventId;
                polledEventClass = eventClass;
            }
        }
    }

    co_return PLDM_SUCCESS;
}

exec::task<int> EventManager::pollForPlatformEventMessage(
    pldm_tid_t tid, uint8_t formatVersion, uint8_t transferOperationFlag,
    uint32_t dataTransferHandle, uint16_t eventIdToAcknowledge,
    uint8_t& completionCode, uint8_t& eventTid, uint16_t& eventId,
    uint32_t& nextDataTransferHandle, uint8_t& transferFlag,
    uint8_t& eventClass, uint32_t& eventDataSize, uint8_t*& eventData,
    uint32_t& eventDataIntegrityChecksum)
{
    Request request(
        sizeof(pldm_msg_hdr) + PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
    auto requestMsg = new (request.data()) pldm_msg;
    auto rc = encode_poll_for_platform_event_message_req(
        0, formatVersion, transferOperationFlag, dataTransferHandle,
        eventIdToAcknowledge, requestMsg, request.size());
    if (rc)
    {
        lg2::error(
            "Failed to encode request PollForPlatformEventMessage for terminus ID {TID}, error {RC} ",
            "TID", tid, "RC", rc);
        co_return rc;
    }

    /* Stop event polling */
    if (!getAvailableState(tid))
    {
        lg2::info(
            "Terminus ID {TID} is not available for PLDM request from {NOW}.",
            "TID", tid, "NOW", pldm::utils::getCurrentSystemTime());
        co_await stdexec::just_stopped();
    }

    const pldm_msg* responseMsg = nullptr;
    size_t responseLen = 0;
    rc = co_await terminusManager.sendRecvPldmMsg(tid, request, &responseMsg,
                                                  &responseLen);
    if (rc)
    {
        lg2::error(
            "Failed to send PollForPlatformEventMessage message for terminus {TID}, error {RC}",
            "TID", tid, "RC", rc);
        co_return rc;
    }

    rc = decode_poll_for_platform_event_message_resp(
        responseMsg, responseLen, &completionCode, &eventTid, &eventId,
        &nextDataTransferHandle, &transferFlag, &eventClass, &eventDataSize,
        (void**)&eventData, &eventDataIntegrityChecksum);
    if (rc)
    {
        lg2::error(
            "Failed to decode response PollForPlatformEventMessage for terminus ID {TID}, error {RC} ",
            "TID", tid, "RC", rc);
        co_return rc;
    }
    if (completionCode != PLDM_SUCCESS)
    {
        lg2::error(
            "Error : PollForPlatformEventMessage for terminus ID {TID}, complete code {CC}.",
            "TID", tid, "CC", completionCode);
        co_return rc;
    }

    co_return completionCode;
}

} // namespace platform_mc
} // namespace pldm
