#include "config.h"

#include "terminus_handler.hpp"

#include <sdeventplus/source/time.hpp>

#include <chrono>
#include <filesystem>

#include "common/flight_recorder.hpp"
#include "host-bmc/custom_dbus.hpp"

namespace pldm
{

namespace terminus
{

using namespace pldm::sensor;
using EpochTimeUS = uint64_t;

std::string fruPath = "/xyz/openbmc_project/pldm/fru";
static constexpr uint16_t MCControlEffecterID = 254;

std::string exec(const char *cmd)
{
	std::array<char, 128> buffer;
	std::string result;
	std::unique_ptr<FILE, int(*)(FILE*)> pipe(popen(cmd, "r"), pclose);
	if (!pipe) {
		std::cerr << "popen() failed!" << std::endl;
		return "failed";
	}
	while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
		result += buffer.data();
	}
	return result;
}

TerminusHandler::TerminusHandler(
    uint8_t eid, sdeventplus::Event& event, sdbusplus::bus::bus& bus,
    pldm::requester::Handler<pldm::requester::Request>* handler,
    pldm::InstanceIdDb& instanceIdDb) :
    eid(eid), bus(bus), event(event), handler(handler),
    instanceIdDb(instanceIdDb), _state(),
    _timer(event, std::bind(&TerminusHandler::pollSensors, this)),
    _timer2(event, std::bind(&TerminusHandler::readSensor, this)),
    _timer3(event,
            std::bind(&TerminusHandler::waitForRASPollingFinished, this)),
    _timer4(event, std::bind(&TerminusHandler::waitForMProRecovery, this))
{}

TerminusHandler::~TerminusHandler()
{
    continuePollSensor = false;
    this->frus.clear();
    this->compNumSensorPDRs.clear();
    this->effecterAuxNamePDRs.clear();
    this->effecterPDRs.clear();
    this->entityAssociationPDRs.clear();
    this->_state.clear();
    this->_sensorObjects.clear();
    this->_effecterLists.clear();
    this->eventDataHndl.reset();
    this->_auxNameMaps.clear();
}

void TerminusHandler::loadAuxNameMapping()
{
    auxNameOverride.clear();
    try
    {
        utils::GetSubTreeResponse response = utils::DBusHandler().getSubtree(
            chassisInventoryPath, 0,
            {"xyz.openbmc_project.Configuration.SensorAuxName"});

        for (const auto& [path, serviceMap] : response)
        {
            /* Use terminus inventory path as prefix to match its SensorAuxName config:
            inventoryPath      : chassis1/terminusA
            SensorAuxName path : chassis1/terminusA_AuxName_Temp
            SensorAuxName path : chassis1/terminusA_AuxName_HealthState

            inventoryPath      : chassis1/terminusB
            SensorAuxName path : chassis1/terminusB_AuxName_Temp
            SensorAuxName path : chassis1/terminusB_AuxName_HealthState
            */
            if (!path.starts_with(inventoryPath))
            {
                continue;
            }

            uint64_t sensorId = utils::DBusHandler().getDbusProperty<uint64_t>(
                path.c_str(), "SensorId",
                "xyz.openbmc_project.Configuration.SensorAuxName");

            std::vector<std::string> auxNames =
                utils::DBusHandler().getDbusProperty<std::vector<std::string>>(
                    path.c_str(), "AuxNames",
                    "xyz.openbmc_project.Configuration.SensorAuxName");
            auxNameOverride[sensorId] = auxNames;
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << std::format(
            "Warning: failed to load SensorAuxName mappping for {}, e.what(): {}\n",
            chassisInventoryPath, e.what());
    }
}

requester::Coroutine TerminusHandler::discoveryTerminus()
{
    std::cerr << "Discovery Terminus: " << unsigned(eid) << std::endl;
    /*
     * 1. Initialize PLDM if PLDM Type is supported
     *
     * 1.1 Get supported PLDM Types
     *
     * 1.2. If PLDM for BIOS control and configuration is supported
     * 1.2.1 Set the date and time using the SetDateTime command
     *
     * 1.3. If PLDM Base Type is supported, get PLDM Base commands
     * 1.3.1 Get TID
     * 1.3.2 Get PLDM Commands
     *
     * 1.4. If FRU Type is supported, issue these FRU commands
     * 1.4.1 Get FRU Meta data via GetFRURecordTableMetadata
     * 1.4.2 Get FRU Table data via GetFRURecordTable
     *
     * 1.5. If PLDM Platform Type is supported, get PLDM Platform commands
     * 1.5.1 Prepare to receive event notification SetEventReceiver
     * 1.5.2 Get all Sensor/Effecter/Association information via GetPDR command
     *
     */
    auto rc = co_await getPLDMTypes();
    if (rc)
    {
        std::cerr << "Failed to getPLDMTypes, rc=" << unsigned(rc) << std::endl;
        removeMCTPEndpoint();
        co_return rc;
    }
    /* Received the response, terminus is on */
    this->responseReceived = true;

    if (supportPLDMType(PLDM_BASE))
    {
        rc = co_await getPLDMCommands();
        if (rc)
        {
            std::cerr << "Failed to getPLDMCommands, rc=" << unsigned(rc)
                      << std::endl;
        }
    }

    if (supportPLDMType(PLDM_BASE))
    {
        rc = co_await getTID();
        if (rc)
        {
            std::cerr << "Failed to getTID, rc=" << unsigned(rc) << std::endl;
            removeMCTPEndpoint();
            co_return PLDM_ERROR;
        }

        devInfo.eid = eid;
        if(devInfo.tid != eid)
        {
            rc = co_await setTID(eid);
            if (rc)
            {
                removeMCTPEndpoint();
                co_return PLDM_ERROR;
            }
        }
    }

    if (supportPLDMType(PLDM_BIOS))
    {
        rc = co_await setDateTime();
        if (rc)
        {
            std::cerr << "Failed to setDateTime, rc=" << unsigned(rc)
                      << std::endl;
        }
    }

    uint16_t totalTableRecords = 0;
    if (supportPLDMType(PLDM_FRU))
    {
        rc = co_await getFRURecordTableMetadata(&totalTableRecords);
        if (rc)
        {
            std::cerr << "Failed to getFRURecordTableMetadata, "
                      << "rc=" << unsigned(rc) << std::endl;
        }
        if (!totalTableRecords)
        {
            std::cerr << "Number of record table is not correct." << std::endl;
        }
    }

    if ((totalTableRecords != 0) && supportPLDMType(PLDM_FRU))
    {
        rc = co_await getFRURecordTable(totalTableRecords);
        if (rc)
        {
            std::cerr << "Failed to getFRURecordTable, "
                      << "rc=" << unsigned(rc) << std::endl;
        }
    }

    /* Check whether the terminus is removed when discoverying */
    if (stopTerminusPolling)
    {
        co_return PLDM_SUCCESS;
    }

    if (supportPLDMType(PLDM_PLATFORM))
    {
        if (debugGetPDR)
        {
            startTime = std::chrono::system_clock::now();
            std::cerr << eidToName.second << " Start GetPDR at "
                      << getCurrentSystemTime() << std::endl;
        }

        rc = co_await getDevPDR(0);
        if (rc)
        {
            std::cerr << "Failed to getDevPDR, rc=" << unsigned(rc)
                      << std::endl;
            removeMCTPEndpoint();
        }
        else
        {
            readCount = 0;
            if (debugGetPDR)
            {
                std::chrono::duration<double> elapsed_seconds =
                    std::chrono::system_clock::now() - startTime;
                std::cerr << eidToName.second << " Finish get all PDR "
                          << elapsed_seconds.count() << "s at "
                          << getCurrentSystemTime() << std::endl;
            }
            if (entityAssociationPDRs.size() > 0)
            {
                createEntityAssociationMap(entityAssociationPDRs);
                createNicAndPortInventory();
            }
            if (this->numericSensorPDRs.size() > 0)
            {
                this->createNumericSensorIntf(this->numericSensorPDRs);
            }
            if (this->stateSensorPDRs.size() > 0)
            {
                this->createStateSensorIntf(this->stateSensorPDRs);
            }
            if (this->compNumSensorPDRs.size() > 0)
            {
                this->createCompactNummericSensorIntf(this->compNumSensorPDRs);
            }
            if (this->effecterAuxNamePDRs.size() > 0)
            {
                this->parseAuxNamePDRs(this->effecterAuxNamePDRs);
            }
            if (this->effecterPDRs.size() > 0)
            {
                this->createNummericEffecterDBusIntf(this->effecterPDRs);
            }
            if (_state.size() > 0)
            {
                createdDbusObject = true;
            }
            updateSensorKeys();
        }
    }

#ifdef AMPERE
    if (supportPLDMType(PLDM_PLATFORM))
    {
        rc = co_await setEventReceiver();
        if (rc)
        {
            std::cerr << "Failed to setEventReceiver, rc=" << unsigned(rc)
                      << std::endl;
        }
    }

    /* Start RAS */
    eventDataHndl = std::make_shared<PldmMessagePollEvent>(eid, event, bus,
                                                           instanceIdDb, handler);
#endif
    co_return PLDM_SUCCESS;
}

bool TerminusHandler::supportPLDMType(const uint8_t type)
{
    if (devInfo.supportedTypes[type / 8].byte & (1 << (type % 8)))
    {
        return true;
    }

    return false;
}

bool TerminusHandler::supportPLDMCommand(const uint8_t type,
                                         const uint8_t command)
{
    if (!supportPLDMType(type))
    {
        return false;
    }
    if (devInfo.supportedCmds[type].cmdTypes[command / 8].byte &
        (1 << (command % 8)))
    {
        return true;
    }

    return false;
}

std::string TerminusHandler::getCurrentSystemTime()
{
    auto currentTime = std::chrono::system_clock::now();
    char buffer[80];
    char buffer1[4];

    auto transformed = currentTime.time_since_epoch().count() / 1000000;
    auto millis = transformed % 1000;

    std::time_t tt;
    tt = std::chrono::system_clock::to_time_t(currentTime);
    auto timeinfo = localtime(&tt);
    strftime(buffer, 80, "%F %H:%M:%S", timeinfo);
    snprintf(buffer1, 4, "%03d", (int)millis);
    return std::string(buffer) + ":" + std::string(buffer1);
}

requester::Coroutine TerminusHandler::getPLDMTypes()
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " get the PLDM Types." << std::endl;

    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto instanceId = instanceIdDb.next(eid);

    auto rc = encode_get_types_req(instanceId, request);
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to encode_get_types_req, rc = " << unsigned(rc)
                  << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_GET_PLDM_TYPES)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << std::endl;
        co_return rc;
    }

    std::vector<bitfield8_t> types(8);
    rc = decode_get_types_resp(response, respMsgLen, &cc, types.data());
    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode_get_types_resp, Message Error: "
                  << "rc=" << unsigned(rc) << ",cc=" << unsigned(cc)
                  << std::endl;
        for (int i = 0; i < 8; i++)
        {
            devInfo.supportedTypes[i].byte = 0;
        }
        co_return rc;
    }
    else
    {
        for (int i = 0; i < 8; i++)
        {
            devInfo.supportedTypes[i] = types[i];
        }
    }

    co_return cc;
}

requester::Coroutine TerminusHandler::getPLDMCommands()
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " get the supported PLDM Types." << std::endl;

    uint8_t type = PLDM_BASE;
    while ((type < PLDM_MAX_TYPES) && supportPLDMType(type))
    {
        auto rc = co_await getPLDMCommand(type);
        if (rc)
        {
            std::cerr << "Failed to getPLDMCommand, Type=" << unsigned(type)
                      << " rc =" << unsigned(rc) << std::endl;
        }
        type++;
    }
    co_return PLDM_SUCCESS;
}

requester::Coroutine TerminusHandler::getPLDMCommand(const uint8_t& pldmTypeIdx)
{
    auto instanceId = instanceIdDb.next(eid);
    Request requestMsg(sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
    auto rc =
        encode_get_commands_req(instanceId, pldmTypeIdx, version, request);
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to encode_get_commands_req, rc = " << unsigned(rc)
                  << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_GET_PLDM_COMMANDS)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    /* Process response */
    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_GET_PLDM_COMMANDS)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    std::vector<bitfield8_t> cmdTypes(32);
    rc = decode_get_commands_resp(response, respMsgLen, &cc, cmdTypes.data());
    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Response Message Error: "
                  << "rc=" << unsigned(rc) << ",cc=" << unsigned(cc)
                  << std::endl;
        for (auto i = 0; i < 32; i++)
        {
            devInfo.supportedCmds[pldmTypeIdx].cmdTypes[i].byte = 0;
        }
        co_return rc;
    }

    uint8_t i = 0;
    for (const auto& cmd : cmdTypes)
    {
        devInfo.supportedCmds[pldmTypeIdx].cmdTypes[i++].byte = cmd.byte;
    }

    co_return cc;
}

requester::Coroutine TerminusHandler::getTID()
{
    std::cerr << "Discovery Terminus: " << unsigned(eid) << " get TID."
              << std::endl;
    auto instanceId = instanceIdDb.next(eid);
    Request requestMsg(sizeof(pldm_msg_hdr));
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto rc = encode_get_tid_req(instanceId, request);
    if (rc)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "encode_get_tid_req failed. rc=" << unsigned(rc)
                  << std::endl;
        ;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_GET_TID)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_GET_TID)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t tid = PLDM_TID_RESERVED;
    rc = decode_get_tid_resp(response, respMsgLen, &cc, &tid);
    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode_get_tid_resp, Message Error: "
                  << "rc=" << unsigned(rc) << ",cc=" << unsigned(cc)
                  << std::endl;
        devInfo.tid = 0xFF;
        co_return cc;
    }

    devInfo.tid = tid;
    std::cerr << "Discovery Terminus: EID=" << unsigned(eid) << " TID="
              << unsigned(tid) << std::endl;

    co_return cc;
}

requester::Coroutine TerminusHandler::setTID(uint8_t tid)
{
    std::cerr << "Discovery Terminus: " << unsigned(eid) << " set TID."
              << std::endl;
    auto instanceId = instanceIdDb.next(eid);
    Request requestMsg(sizeof(pldm_msg_hdr) + sizeof(tid));
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto rc = encode_set_tid_req(instanceId, tid, request);
    if (rc)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "encode_set_tid_req failed. rc=" << unsigned(rc)
                  << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_SET_TID)
                  << ", rc=" << unsigned(rc) << std::endl;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || respMsgLen != PLDM_SET_TID_RESP_BYTES)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BASE)
                  << ", cmd= " << unsigned(PLDM_SET_TID)
                  << ", rc=" << unsigned(rc) << std::endl;
        co_return rc;
    }
    // No decode_set_tid_resp in libpldm, decode by ourself.
    cc = response->payload[0];
    if (cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to setTID, cc=" << unsigned(cc)
                  << std::endl;
        devInfo.tid = 0xFF;
        co_return cc;
    }

    devInfo.tid = tid;
    std::cerr << "Discovery Terminus: EID=" << unsigned(eid) << "  set TID="
              << unsigned(devInfo.tid) << std::endl;

    co_return cc;
}

void TerminusHandler::setInventoryPath(const std::string& path)
{
    inventoryPath = path;
    terminusName = std::filesystem::path(inventoryPath).filename();
    chassisInventoryPath = pldm::utils::findParent(inventoryPath);
}

requester::Coroutine TerminusHandler::setEventReceiver()
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " set Event Receiver." << std::endl;
    uint8_t eventMessageGlobalEnable =
        PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
    uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
    /* default BMC EID is 8 */
    uint8_t eventReceiverAddressInfo = 0x08;
    uint16_t heartbeatTimer = 0x78;

    auto instanceId = instanceIdDb.next(eid);
    Request requestMsg(sizeof(pldm_msg_hdr) +
                       PLDM_SET_EVENT_RECEIVER_REQ_BYTES);

    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto rc = encode_set_event_receiver_req(
        instanceId, eventMessageGlobalEnable, transportProtocolType,
        eventReceiverAddressInfo, heartbeatTimer, request);
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to encode_set_event_receiver_req, rc = "
                  << unsigned(rc) << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_PLATFORM)
                  << ", cmd= " << unsigned(PLDM_SET_EVENT_RECEIVER)
                  << ", rc=" << rc << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_PLATFORM)
                  << ", cmd= " << unsigned(PLDM_SET_EVENT_RECEIVER)
                  << ", rc=" << rc << std::endl;
        ;
        co_return rc;
    }

    rc = decode_set_event_receiver_resp(response, respMsgLen, &cc);

    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode_set_event_receiver_resp,"
                  << ", rc=" << unsigned(rc) << " cc=" << unsigned(cc)
                  << std::endl;
        co_return rc;
    }

    co_return cc;
}

void epochToBCDTime(const uint64_t& timeSec, uint8_t* seconds, uint8_t* minutes,
                    uint8_t* hours, uint8_t* day, uint8_t* month,
                    uint16_t* year)
{
    auto t = time_t(timeSec);
    auto time = localtime(&t);

    *seconds = (uint8_t)pldm::utils::decimalToBcd(time->tm_sec);
    *minutes = (uint8_t)pldm::utils::decimalToBcd(time->tm_min);
    *hours = (uint8_t)pldm::utils::decimalToBcd(time->tm_hour);
    *day = (uint8_t)pldm::utils::decimalToBcd(time->tm_mday);
    *month = (uint8_t)pldm::utils::decimalToBcd(
        time->tm_mon + 1); // The number of months in the range
                           // 0 to 11.PLDM expects range 1 to 12
    *year = (uint16_t)pldm::utils::decimalToBcd(
        time->tm_year + 1900); // The number of years since 1900
}

requester::Coroutine TerminusHandler::setDateTime()
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " update date time to terminus." << std::endl;
    uint8_t seconds = 0;
    uint8_t minutes = 0;
    uint8_t hours = 0;
    uint8_t day = 0;
    uint8_t month = 0;
    uint16_t year = 0;

    constexpr auto timeInterface = "xyz.openbmc_project.Time.EpochTime";
    constexpr auto bmcTimePath = "/xyz/openbmc_project/time/bmc";
    EpochTimeUS timeUsec;

    try
    {
        timeUsec = pldm::utils::DBusHandler().getDbusProperty<EpochTimeUS>(
            bmcTimePath, "Elapsed", timeInterface);
    }
    catch (const sdbusplus::exception::exception& e)
    {
        std::cerr << "Error getting time, PATH=" << bmcTimePath
                  << " TIME INTERACE=" << timeInterface << std::endl;
        co_return PLDM_ERROR;
    }

    uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
                           std::chrono::microseconds(timeUsec))
                           .count();

    epochToBCDTime(timeSec, &seconds, &minutes, &hours, &day, &month, &year);
    std::cerr << "SetDateTime timeUsec=" << timeUsec << " seconds="
              << unsigned(seconds) << " minutes=" << unsigned(minutes)
              << " hours=" << unsigned(hours) << " year=" << year << std::endl;

    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                    sizeof(struct pldm_set_date_time_req));
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto instanceId = instanceIdDb.next(eid);

    auto rc = encode_set_date_time_req(instanceId, seconds, minutes, hours, day,
                                       month, year, request,
                                       sizeof(struct pldm_set_date_time_req));
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to encode_set_date_time_req, rc = " << unsigned(rc)
                  << std::endl;
        co_return PLDM_ERROR;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BIOS)
                  << ", cmd= " << unsigned(PLDM_SET_DATE_TIME)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_BIOS)
                  << ", cmd= " << unsigned(PLDM_SET_DATE_TIME)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    rc = decode_set_date_time_resp(response, respMsgLen, &cc);

    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Response Message Error: "
                  << "rc=" << unsigned(rc) << ",cc=" << unsigned(cc)
                  << std::endl;
        co_return rc;
    }

    std::cerr << "Success SetDateTime to terminus " << devInfo.tid << std::endl;

    co_return cc;
}

std::string fruFieldValuestring(const uint8_t* value, const uint8_t& length)
{
    return std::string(reinterpret_cast<const char*>(value), length);
}

static uint32_t fruFieldParserU32(const uint8_t* value, const uint8_t& length)
{
    assert(length == 4);
    uint32_t v;
    std::memcpy(&v, value, length);
    return v;
}

static std::string fruFieldParserTimestamp(const uint8_t*, uint8_t)
{
    return std::string("TODO");
}

/** @brief Check if a pointer is go through end of table
 *  @param[in] table - pointer to FRU record table
 *  @param[in] p - pointer to each record of FRU record table
 *  @param[in] table_size - FRU table size
 */
bool isTableEnd(const uint8_t* table, const uint8_t* p, size_t& tableSize)
{
    auto offset = p - table;
    return (tableSize - offset) <= 7;
}

void TerminusHandler::parseFruRecordTable(const uint8_t* fruData,
                                          size_t& fruLen)
{
    std::string tidFRUObjPath;

    if (devInfo.tid == PLDM_TID_RESERVED)
    {
        std::cerr << "Invalid TID " << std::endl;
        return;
    }
    if (eidToName.second != "")
    {
        tidFRUObjPath = fruPath + "/" + eidToName.second;
    }
    else
    {
        tidFRUObjPath = fruPath + "/" + std::to_string(devInfo.tid);
    }

    auto fruPtr = std::make_shared<pldm::dbus_api::FruReq>(bus, tidFRUObjPath);
    frus.emplace(devInfo.tid, fruPtr);

    auto p = fruData;
    while (!isTableEnd(fruData, p, fruLen))
    {
        auto record = reinterpret_cast<const pldm_fru_record_data_format*>(p);

        p += sizeof(pldm_fru_record_data_format) - sizeof(pldm_fru_record_tlv);

        for (int i = 0; i < record->num_fru_fields; i++)
        {
            auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(p);
            if (record->record_type == PLDM_FRU_RECORD_TYPE_GENERAL)
            {
                switch (tlv->type)
                {
                    case PLDM_FRU_FIELD_TYPE_CHASSIS:
                        fruPtr->chassisType(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_MODEL:
                        fruPtr->model(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_PN:
                        fruPtr->pn(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_SN:
                        fruPtr->sn(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_MANUFAC:
                        fruPtr->manufacturer(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_MANUFAC_DATE:
                        fruPtr->manufacturerDate(
                            fruFieldParserTimestamp(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_VENDOR:
                        fruPtr->vendor(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_NAME:
                        fruPtr->name(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_SKU:
                        fruPtr->sku(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_VERSION:
                    {
                        auto versionStr = fruFieldValuestring(tlv->value,
                                                              tlv->length);
                        fruPtr->version(versionStr);
                        pldm::dbus::CustomDBus::getCustomDBus()
                            .assignSoftwareVersionPath(versionStr, eid);
                        break;
                    }
                    case PLDM_FRU_FIELD_TYPE_ASSET_TAG:
                        fruPtr->assetTag(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_DESC:
                        fruPtr->description(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_EC_LVL:
                        fruPtr->ecLevel(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_OTHER:
                        fruPtr->other(
                            fruFieldValuestring(tlv->value, tlv->length));
                        break;
                    case PLDM_FRU_FIELD_TYPE_IANA:
                        fruPtr->iana(
                            fruFieldParserU32(tlv->value, tlv->length));
                        break;
                }
            }
            p += sizeof(pldm_fru_record_tlv) - 1 + tlv->length;
        }
    }
}

requester::Coroutine TerminusHandler::getFRURecordTableMetadata(uint16_t* total)
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " get FRU record Table Meta Data." << std::endl;
    auto instanceId = instanceIdDb.next(eid);
    Request requestMsg(sizeof(pldm_msg_hdr) +
                       PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto rc = encode_get_fru_record_table_metadata_req(
        instanceId, request, requestMsg.size() - sizeof(pldm_msg_hdr));
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to encode_get_fru_record_table_metadata_req, rc = "
                  << unsigned(rc) << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_FRU)
                  << ", cmd= " << unsigned(PLDM_GET_FRU_RECORD_TABLE_METADATA)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_FRU)
                  << ", cmd= " << unsigned(PLDM_GET_FRU_RECORD_TABLE_METADATA)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t fru_data_major_version, fru_data_minor_version;
    uint32_t fru_table_maximum_size, fru_table_length;
    uint16_t total_record_set_identifiers;
    uint32_t checksum;
    rc = decode_get_fru_record_table_metadata_resp(
        response, respMsgLen, &cc, &fru_data_major_version,
        &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
        &total_record_set_identifiers, total, &checksum);

    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode get fru record table metadata resp, "
                     "Message Error: "
                  << "rc=" << unsigned(rc) << ", cc=" << unsigned(cc)
                  << std::endl;
        co_return rc;
    }

    co_return rc;
}

requester::Coroutine
    TerminusHandler::getFRURecordTable(const uint16_t& totalTableRecords)
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " get FRU record Table." << std::endl;
    if (!totalTableRecords)
    {
        std::cerr << "Number of record table is not correct." << std::endl;
        co_return PLDM_ERROR;
    }

    auto instanceId = instanceIdDb.next(eid);
    Request requestMsg(sizeof(pldm_msg_hdr) +
                       PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);

    // send the getFruRecordTable command
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto rc = encode_get_fru_record_table_req(
        instanceId, 0, PLDM_GET_FIRSTPART, request,
        requestMsg.size() - sizeof(pldm_msg_hdr));
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to encode_get_fru_record_table_req, rc = "
                  << unsigned(rc) << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_FRU)
                  << ", cmd= " << unsigned(PLDM_GET_FRU_RECORD_TABLE)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_FRU)
                  << ", cmd= " << unsigned(PLDM_GET_FRU_RECORD_TABLE)
                  << ", rc=" << unsigned(rc) << std::endl;
        ;
        co_return rc;
    }

    uint32_t nextDataTransferHandle = 0;
    uint8_t transferFlag = 0;
    size_t fruRecordTableLength = 0;
    std::vector<uint8_t> fruRecordTableData(respMsgLen - sizeof(pldm_msg_hdr));

    auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
    rc = decode_get_fru_record_table_resp(
        responsePtr, respMsgLen - sizeof(pldm_msg_hdr), &cc,
        &nextDataTransferHandle, &transferFlag, fruRecordTableData.data(),
        &fruRecordTableLength);

    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr
            << "Failed to decode get fru record table resp, Message Error: "
            << "rc=" << unsigned(rc) << ", cc=" << unsigned(cc) << std::endl;
        co_return rc;
    }

    parseFruRecordTable(fruRecordTableData.data(), fruRecordTableLength);

    co_return cc;
}

requester::Coroutine TerminusHandler::getDevPDR(uint32_t nextRecordHandle)
{
    std::cerr << "Discovery Terminus: " << unsigned(eid)
              << " get terminus PDRs." << std::endl;
    do
    {
        /* Check whether the terminus is removed when getting PDRs */
        if (stopTerminusPolling)
        {
            co_return PLDM_SUCCESS;
        }

        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                        PLDM_GET_PDR_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        uint32_t recordHandle{};
        if (nextRecordHandle)
        {
            recordHandle = nextRecordHandle;
        }
        auto instanceId = instanceIdDb.next(eid);

        auto rc =
            encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
                               UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
        if (rc != PLDM_SUCCESS)
        {
            instanceIdDb.free(eid, instanceId);
            std::cerr << "Failed to encode_get_pdr_req, rc = " << unsigned(rc)
                      << std::endl;
            co_return rc;
        }

        Response responseMsg{};
        rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                                 responseMsg);
        if (rc)
        {
            std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                      << ", instanceId=" << unsigned(instanceId)
                      << ", type=" << unsigned(PLDM_PLATFORM)
                      << ", cmd= " << unsigned(PLDM_GET_PDR)
                      << ", rc=" << unsigned(rc) << std::endl;
            ;
            co_return rc;
        }

        auto respMsgLen = responseMsg.size() - sizeof(struct pldm_msg_hdr);
        auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
        if (response == nullptr || !respMsgLen)
        {
            std::cerr << "No response received for sendRecvPldmMsg, EID="
                      << unsigned(eid) << ", instanceId="
                      << unsigned(instanceId) << ", type="
                      << unsigned(PLDM_PLATFORM) << ", cmd= "
                      << unsigned(PLDM_GET_PDR) << ", rc="
                      << unsigned(rc) << std::endl;
            ;
            co_return rc;
        }
        rc = co_await processDevPDRs(eid, response, respMsgLen,
                                     &nextRecordHandle, recordHandle);
        if (rc)
        {
            std::cerr << "Failed to send processDevPDRs, EID=" << unsigned(eid)
                      << ", rc=" << unsigned(rc) << std::endl;
            ;
            co_return rc;
        }
    } while (nextRecordHandle != 0);

    if (!nextRecordHandle)
    {
        co_return PLDM_SUCCESS;
    }

    co_return PLDM_ERROR;
}

requester::Coroutine TerminusHandler::processDevPDRs(mctp_eid_t& /*eid*/,
                                                     const pldm_msg* response,
                                                     size_t& respMsgLen,
                                                     uint32_t* nextRecordHandle,
                                                     uint32_t recordHandle)
{
    uint8_t tlEid = 0;
    uint32_t rh = 0;
    uint8_t completionCode{};
    uint32_t nextDataTransferHandle{};
    uint8_t transferFlag{};
    uint16_t respCount{};
    uint8_t transferCRC{};
    if (response == nullptr || !respMsgLen)
    {
        std::cerr << "Failed to receive response for the GetPDR"
                     " command \n";
        co_return PLDM_ERROR;
    }

    auto rc = decode_get_pdr_resp(
        response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
        nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
        nullptr, 0, &transferCRC);
    if (rc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode_get_pdr_resp, rc = " << unsigned(rc)
                  << std::endl;
        co_return rc;
    }

    std::vector<uint8_t> pdr(respCount, 0);
    rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
                             nextRecordHandle, &nextDataTransferHandle,
                             &transferFlag, &respCount, pdr.data(), respCount,
                             &transferCRC);

    if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode_get_pdr_resp: "
                  << "rc=" << unsigned(rc)
                  << ", cc=" << unsigned(completionCode) << std::endl;
        co_return rc;
    }

    /*
     * Temporary: If PDR is multi-part PDR just get the first part then go to
     * next PDRs
     * Todo: Support multi-part in getting PDRs.
     */
    if ((*nextRecordHandle) && (transferFlag != PLDM_END) &&
        (transferFlag != PLDM_START_AND_END))
    {
        *nextRecordHandle = recordHandle + 1;
    }

    // when nextRecordHandle is 0, we need the recordHandle of the last
    // PDR and not 0-1.
    if (!(*nextRecordHandle))
    {
        rh = *nextRecordHandle;
    }
    else
    {
        rh = *nextRecordHandle - 1;
    }

    auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
    if (!rh)
    {
        rh = pdrHdr->record_handle;
    }

    if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
    {
        /* Temporary remove merge Entity Association feature */
        // this->mergeEntityAssociations(pdr);
        this->entityAssociationPDRs.emplace_back(pdr);
    }
    else if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
    {
        auto tlpdr =
            reinterpret_cast<const pldm_terminus_locator_pdr*>(pdr.data());

        terminusHandle = tlpdr->terminus_handle;
        auto terminus_locator_type = tlpdr->terminus_locator_type;
        if (terminus_locator_type == PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
        {
            auto locatorValue =
                reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>(
                    tlpdr->terminus_locator_value);
            tlEid = static_cast<uint8_t>(locatorValue->eid);
        }
        tlPDRInfo.insert_or_assign(
            tlpdr->terminus_handle,
            std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity));
    }
    else if (pdrHdr->type == PLDM_NUMERIC_SENSOR_PDR)
    {
        std::vector<uint8_t> parsedPdr(sizeof(pldm_numeric_sensor_value_pdr),
                                       0);
        rc = decode_numeric_sensor_pdr_data(
            pdr.data(), respCount,
            reinterpret_cast<pldm_numeric_sensor_value_pdr*>(parsedPdr.data()));
        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "Failed to decode_numeric_sensor_pdr_data, rc = " << rc
                      << std::endl;
            co_return rc;
        }
        this->numericSensorPDRs.emplace_back(parsedPdr);
    }
    else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
    {
        this->stateSensorPDRs.emplace_back(pdr);
    }
    else if (pdrHdr->type == PLDM_COMPACT_NUMERIC_SENSOR_PDR)
    {
        this->compNumSensorPDRs.emplace_back(pdr);
    }
    else if (pdrHdr->type == PLDM_NUMERIC_EFFECTER_PDR)
    {
        this->effecterPDRs.emplace_back(pdr);
    }
    else if (pdrHdr->type == PLDM_EFFECTER_AUXILIARY_NAMES_PDR)
    {
        this->effecterAuxNamePDRs.emplace_back(pdr);
    }

    co_return PLDM_SUCCESS;
}

static void fillNumericSensorThreshold(const pldm_numeric_sensor_value_pdr* pdr,
                                       PldmSensorInfo& sensorInfo)
{
    BitField8 bitfield(pdr->supported_thresholds);
    sensorInfo.warningHigh = std::numeric_limits<double>::quiet_NaN();
    sensorInfo.warningLow = std::numeric_limits<double>::quiet_NaN();
    sensorInfo.criticalHigh = std::numeric_limits<double>::quiet_NaN();
    sensorInfo.criticalLow = std::numeric_limits<double>::quiet_NaN();
    sensorInfo.fatalHigh = std::numeric_limits<double>::quiet_NaN();
    sensorInfo.fatalLow = std::numeric_limits<double>::quiet_NaN();

    if (bitfield.bits.bit0)
    {
        sensorInfo.warningHigh = pldm::utils::castNumericSensorRangeField(
            static_cast<pldm_range_field_format>(pdr->range_field_format),
            pdr->warning_high);
    }
    if (bitfield.bits.bit1)
    {
        sensorInfo.criticalHigh = pldm::utils::castNumericSensorRangeField(
            static_cast<pldm_range_field_format>(pdr->range_field_format),
            pdr->critical_high);
    }
    if (bitfield.bits.bit2)
    {
        sensorInfo.fatalHigh = pldm::utils::castNumericSensorRangeField(
            static_cast<pldm_range_field_format>(pdr->range_field_format),
            pdr->fatal_high);
    }
    if (bitfield.bits.bit3)
    {
        sensorInfo.warningLow = pldm::utils::castNumericSensorRangeField(
            static_cast<pldm_range_field_format>(pdr->range_field_format),
            pdr->warning_low);
    }
    if (bitfield.bits.bit4)
    {
        sensorInfo.criticalLow = pldm::utils::castNumericSensorRangeField(
            static_cast<pldm_range_field_format>(pdr->range_field_format),
            pdr->critical_low);
    }
    if (bitfield.bits.bit5)
    {
        sensorInfo.fatalLow = pldm::utils::castNumericSensorRangeField(
            static_cast<pldm_range_field_format>(pdr->range_field_format),
            pdr->fatal_low);
    }
}

std::string TerminusHandler::generateSensorName(uint16_t sensorId)
{
    // Default sensor name
    std::string sensorName = std::format("TID_{}_SensorId_{}", devInfo.tid,
                                         sensorId);
    // Todo: check and use Sensor Auxiliary Names PDR

    // Check and use aux name override from EM config
    if (auxNameOverride.count(sensorId))
    {
        const std::vector<std::string>& auxNames = auxNameOverride[sensorId];
        if (auxNames.size() > 0)
        {
            sensorName = auxNames[0];
            std::string chassisName =
                std::filesystem::path(chassisInventoryPath).filename();
            if (!sensorName.starts_with(chassisName))
            {
                // Add chassis and terminus prefix in case that the sensorName
                // doesn't have those info.
                sensorName = std::format("{}_{}_{}", chassisName, terminusName,
                                         sensorName);
            }
        }
    }

    return sensorName;
}

void TerminusHandler::createNumericSensorIntf(const PDRList& sensorPDRs)
{
    for (const auto& sensorPDR : sensorPDRs)
    {
        const pldm_numeric_sensor_value_pdr* pdr =
            reinterpret_cast<const pldm_numeric_sensor_value_pdr*>(
                sensorPDR.data());

        // Todo: check for duplicate sensorId
        uint16_t sensorId = pdr->sensor_id;
        PldmSensorInfo sensorInfo{};
        sensorInfo.entityType = pdr->entity_type;
        sensorInfo.entityInstance = pdr->entity_instance;
        sensorInfo.containerId = pdr->container_id;
        sensorInfo.baseUnit = pdr->base_unit;
        sensorInfo.unitModifier = pdr->unit_modifier;
        sensorInfo.offset = pdr->offset;
        sensorInfo.resolution = pdr->resolution;
        sensorInfo.occurrenceRate = pdr->rate_unit;
        sensorInfo.maxValue = pldm::utils::castSensorDataToDouble(
            static_cast<pldm_sensor_readings_data_type>(pdr->sensor_data_size),
            pdr->max_readable);
        sensorInfo.minValue = pldm::utils::castSensorDataToDouble(
            static_cast<pldm_sensor_readings_data_type>(pdr->sensor_data_size),
            pdr->min_readable);
        fillNumericSensorThreshold(pdr, sensorInfo);
        sensorInfo.sensorName = generateSensorName(sensorId);
        std::cerr << std::format("tid: {}, Adding numeric sensor: {}\n",
                                 devInfo.tid, sensorInfo.sensorName);

        auto sensorObject = std::make_unique<PldmSensor>(
            bus, sensorInfo.sensorName, sensorInfo.baseUnit,
            sensorInfo.unitModifier, sensorInfo.offset, sensorInfo.resolution,
            sensorInfo.warningHigh, sensorInfo.warningLow,
            sensorInfo.criticalHigh, sensorInfo.criticalLow);
        sensorObject->initMinMaxValue(sensorInfo.minValue, sensorInfo.maxValue);
        sensorObject->setChassisInventoryPath(chassisInventoryPath);

        PLDMEntity entity{pdr->entity_type, pdr->entity_instance,
                          pdr->container_id};
        if (entityToInventoryMap.contains(entity))
        {
            sensorObject->setInventoryObject(entityToInventoryMap[entity]);
        }

        auto object = sensorObject->createSensor();
        if (object)
        {
            auto value = std::make_tuple(pdr->sensor_id,
                                         std::move((*object).second));
            auto key = std::make_tuple(eid, pdr->sensor_id, pdr->hdr.type);

            _sensorObjects[key] = std::move(sensorObject);
            _state[std::move(key)] = std::move(value);
        }
    }
}

void TerminusHandler::createCompactNummericSensorIntf(const PDRList& sensorPDRs)
{
    /** @brief Store the added sensor D-Bus object path */
    std::vector<uint16_t> _addedSensorId;
    for (const auto& sensorPDR : sensorPDRs)
    {
        auto pdr = reinterpret_cast<const pldm_compact_numeric_sensor_pdr*>(
            sensorPDR.data());

        auto it = std::find(_addedSensorId.begin(), _addedSensorId.end(),
                            pdr->sensor_id);
        if (it != _addedSensorId.end())
        {
            std::cerr << "Sensor " << pdr->sensor_id << " added." << std::endl;
            continue;
        }
        _addedSensorId.emplace_back(pdr->sensor_id);

        PldmSensorInfo sensorInfo{};
        auto terminusHandle = pdr->terminus_handle;
        sensorInfo.entityType = pdr->entity_type;
        sensorInfo.entityInstance = pdr->entity_instance;
        sensorInfo.containerId = pdr->container_id;
        sensorInfo.sensorNameLength = pdr->sensor_name_length;
        if (sensorInfo.sensorNameLength == 0)
        {
            sensorInfo.sensorName =
                "SensorId" + std::to_string(unsigned(pdr->sensor_id));
        }
        else
        {
            std::string sTemp(reinterpret_cast<char const*>(pdr->sensor_name),
                              sensorInfo.sensorNameLength);
            size_t pos = 0;
            while ((pos = sTemp.find(" ")) != std::string::npos)
            {
                sTemp.replace(pos, 1, "_");
            }
            sensorInfo.sensorName = sTemp;
        }

        sensorInfo.baseUnit = pdr->base_unit;
        sensorInfo.unitModifier = pdr->unit_modifier;
        sensorInfo.offset = 0;
        sensorInfo.resolution = 1;
        sensorInfo.occurrenceRate = pdr->occurrence_rate;
        sensorInfo.rangeFieldSupport = pdr->range_field_support;
        sensorInfo.warningHigh = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.warningLow = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.criticalHigh = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.criticalLow = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.fatalHigh = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.fatalLow = std::numeric_limits<double>::quiet_NaN();
        if (pdr->range_field_support.bits.bit0)
        {
            sensorInfo.warningHigh = double(pdr->warning_high);
        }
        if (pdr->range_field_support.bits.bit1)
        {
            sensorInfo.warningLow = double(pdr->warning_low);
        }
        if (pdr->range_field_support.bits.bit2)
        {
            sensorInfo.criticalHigh = double(pdr->critical_high);
        }
        if (pdr->range_field_support.bits.bit3)
        {
            sensorInfo.criticalLow = double(pdr->critical_low);
        }
        if (pdr->range_field_support.bits.bit4)
        {
            sensorInfo.fatalHigh = double(pdr->fatal_high);
        }
        if (pdr->range_field_support.bits.bit5)
        {
            sensorInfo.fatalLow = double(pdr->fatal_low);
        }

        auto terminusId = PLDM_TID_RESERVED;
        try
        {
            terminusId = std::get<0>(tlPDRInfo.at(terminusHandle));
        }
        catch (const std::out_of_range& e)
        {
            // Do nothing
        }

        /* There is TID mapping */
        if (eidToName.second != "")
        {
            /* PREFIX */
            if (eidToName.first == true)
            {
                sensorInfo.sensorName =
                    eidToName.second + sensorInfo.sensorName;
            }
            else
            {
                sensorInfo.sensorName =
                    sensorInfo.sensorName + eidToName.second;
            }
        }
        else
        {
            sensorInfo.sensorName = sensorInfo.sensorName + "_TID" +
                                    std::to_string(unsigned(terminusId));
        }
        std::cerr << "Adding sensor name: " << sensorInfo.sensorName
                  << std::endl;

        auto sensorObject = std::make_unique<PldmSensor>(
            bus, sensorInfo.sensorName, sensorInfo.baseUnit,
            sensorInfo.unitModifier, sensorInfo.offset, sensorInfo.resolution,
            sensorInfo.warningHigh, sensorInfo.warningLow,
            sensorInfo.criticalHigh, sensorInfo.criticalLow);

        auto object = sensorObject->createSensor();
        if (object)
        {
            auto value =
                std::make_tuple(pdr->sensor_id, std::move((*object).second));
            auto key = std::make_tuple(eid, pdr->sensor_id, pdr->hdr.type);

            _sensorObjects[key] = std::move(sensorObject);
            _state[std::move(key)] = std::move(value);
        }
    }

    return;
}

void TerminusHandler::createNummericEffecterDBusIntf(const PDRList& sensorPDRs)
{
    std::vector<auxNameKey> _addedEffecter;

    for (const auto& sensorPDR : sensorPDRs)
    {
        auto pdr = reinterpret_cast<const pldm_numeric_effecter_value_pdr*>(
            sensorPDR.data());
        auxNameKey namekey =
            std::make_tuple(pdr->terminus_handle, pdr->effecter_id);

        auto it =
            std::find(_addedEffecter.begin(), _addedEffecter.end(), namekey);
        if (it != _addedEffecter.end())
        {
            std::cerr << "Effecter " << pdr->effecter_id << " existed."
                      << std::endl;
            continue;
        }
        _addedEffecter.emplace_back(namekey);

        PldmSensorInfo sensorInfo{};
        auto terminusHandle = pdr->terminus_handle;
        sensorInfo.entityType = pdr->entity_type;
        sensorInfo.entityInstance = pdr->entity_instance;
        sensorInfo.containerId = pdr->container_id;

        std::string sTemp = "";
        if (_auxNameMaps.find(namekey) != _auxNameMaps.end())
        {
            try
            {
                /* Use first name of first sensor idx for effecter name */
                sTemp = get<1>(_auxNameMaps[namekey][0][0]);
            }
            catch (const std::exception& e)
            {
                std::cerr << "Failed to get name of Aux Name Key : "
                          << get<0>(namekey) << ":" << get<1>(namekey) << '\n';
                sTemp =
                    "Effecter_" + std::to_string(unsigned(pdr->effecter_id));
            }
        }
        else
        {
            std::cerr << "No Aux Name of effecter : " << get<0>(namekey) << ":"
                      << get<1>(namekey) << '\n';
            sTemp = "Effecter_" + std::to_string(unsigned(pdr->effecter_id));
        }

        size_t pos = 0;
        while ((pos = sTemp.find(" ")) != std::string::npos)
        {
            sTemp.replace(pos, 1, "_");
        }
        sensorInfo.sensorName = sTemp;
        sensorInfo.sensorNameLength = sTemp.length();

        sensorInfo.baseUnit = pdr->base_unit;
        sensorInfo.unitModifier = pdr->unit_modifier;
        sensorInfo.offset = pdr->offset;
        sensorInfo.resolution = pdr->resolution;
        sensorInfo.occurrenceRate = pdr->rate_unit;
        sensorInfo.rangeFieldSupport = pdr->range_field_support;
        sensorInfo.warningHigh = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.warningLow = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.criticalHigh = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.criticalLow = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.fatalHigh = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.fatalLow = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.maxSetTable = std::numeric_limits<double>::quiet_NaN();
        sensorInfo.minSetTable = std::numeric_limits<double>::quiet_NaN();

        switch (pdr->effecter_data_size)
        {
            case PLDM_SENSOR_DATA_SIZE_UINT8:
                sensorInfo.maxSetTable =
                    static_cast<double>(pdr->max_settable.value_u8);
                sensorInfo.minSetTable =
                    static_cast<double>(pdr->min_settable.value_u8);
                break;
            case PLDM_SENSOR_DATA_SIZE_SINT8:
                sensorInfo.maxSetTable =
                    static_cast<double>(pdr->max_settable.value_s8);
                sensorInfo.minSetTable =
                    static_cast<double>(pdr->min_settable.value_s8);
                break;
            case PLDM_SENSOR_DATA_SIZE_UINT16:
                sensorInfo.maxSetTable =
                    static_cast<double>(pdr->max_settable.value_u16);
                sensorInfo.minSetTable =
                    static_cast<double>(pdr->min_settable.value_u16);
                break;
            case PLDM_SENSOR_DATA_SIZE_SINT16:
                sensorInfo.maxSetTable =
                    static_cast<double>(pdr->max_settable.value_s16);
                sensorInfo.minSetTable =
                    static_cast<double>(pdr->min_settable.value_s16);
                break;
            case PLDM_SENSOR_DATA_SIZE_UINT32:
                sensorInfo.maxSetTable =
                    static_cast<double>(pdr->max_settable.value_u32);
                sensorInfo.minSetTable =
                    static_cast<double>(pdr->min_settable.value_u32);
                break;
            case PLDM_SENSOR_DATA_SIZE_SINT32:
                sensorInfo.maxSetTable =
                    static_cast<double>(pdr->max_settable.value_s32);
                sensorInfo.minSetTable =
                    static_cast<double>(pdr->min_settable.value_s32);
                break;
            default:
                break;
        }

        auto terminusId = PLDM_TID_RESERVED;
        try
        {
            terminusId = std::get<0>(tlPDRInfo.at(terminusHandle));
        }
        catch (const std::out_of_range& e)
        {
            // Do nothing
        }

        /* There is TID mapping */
        if (eidToName.second != "")
        {
            /* PREFIX */
            if (eidToName.first == true)
            {
                sensorInfo.sensorName =
                    eidToName.second + sensorInfo.sensorName;
            }
            else
            {
                sensorInfo.sensorName =
                    sensorInfo.sensorName + eidToName.second;
            }
        }
        else
        {
            sensorInfo.sensorName = sensorInfo.sensorName + "_TID" +
                                    std::to_string(unsigned(terminusId));
        }
        std::cerr << "Adding effecter name: " << sensorInfo.sensorName
                  << std::endl;

        auto sensorObj = std::make_unique<PldmSensor>(
            bus, sensorInfo.sensorName, sensorInfo.baseUnit,
            sensorInfo.unitModifier, sensorInfo.offset, sensorInfo.resolution,
            sensorInfo.warningHigh, sensorInfo.warningLow,
            sensorInfo.criticalHigh, sensorInfo.criticalLow);

        sensorObj->initMinMaxValue(sensorInfo.minSetTable,
                                   sensorInfo.maxSetTable);
        auto object = sensorObj->createSensor();
        if (object)
        {
            auto value =
                std::make_tuple(pdr->effecter_id, std::move((*object).second));
            auto key = std::make_tuple(eid, pdr->effecter_id, pdr->hdr.type);

            _sensorObjects[key] = std::move(sensorObj);
            _effecterLists.emplace_back(key);
            _state[std::move(key)] = std::move(value);
        }
    }

    return;
}

void TerminusHandler::createStateSensorIntf(const PDRList& sensorPDRs)
{
    for (const auto& sensorPDR : sensorPDRs)
    {
        const pldm_state_sensor_pdr* pdr =
            reinterpret_cast<const pldm_state_sensor_pdr*>(sensorPDR.data());

        std::string sensorName = generateSensorName(pdr->sensor_id);
        std::cerr << std::format("tid: {}, Adding state sensor: {}\n",
                                 devInfo.tid, sensorName);

        if (pdr->composite_sensor_count < 1 || pdr->composite_sensor_count > 8)
        {
            std::cerr << sensorName << ": Invalid composite_sensor_count: "
                      << pdr->composite_sensor_count << std::endl;
            continue;  // Processes next PDR
        }

        auto sensorObject = std::make_unique<PldmStateSensor>(bus, sensorName);

        const uint8_t* pointer = pdr->possible_states;
        const uint8_t* end = sensorPDR.data() + sensorPDR.size();
        bool invalidPdr = false;
        for (int i = 0; i < pdr->composite_sensor_count; i++)
        {
            if (pointer > end)
            {
                std::cerr << sensorName << ": Invalid state sensor PDR"
                          << std::endl;
                invalidPdr = true;
                break;
            }
            auto possibleState =
                reinterpret_cast<const state_sensor_possible_states*>(pointer);
            uint16_t stateSetId = possibleState->state_set_id;
            sensorObject->addStateSet(stateSetId);

            uint8_t possibleStatesSize = possibleState->possible_states_size;
            pointer += (sizeof(possibleState->state_set_id) +
                        sizeof(possibleState->possible_states_size) +
                        possibleStatesSize);
        }

        if (invalidPdr) break;

        PLDMEntity entity{pdr->entity_type, pdr->entity_instance,
                          pdr->container_id};
        if (entityToInventoryMap.contains(entity))
        {
            sensorObject->setInventoryObject(entityToInventoryMap[entity]);
        }

        auto object = sensorObject->createStateSensor();
        if (object)
        {
            // Todo: clean this piece of code, it's not straight forward.
            auto key = std::make_tuple(eid, pdr->sensor_id, pdr->hdr.type);
            auto value = std::make_tuple(pdr->sensor_id,
                                         std::move((*object).second));
            _stateSensorObjects[key] = std::move(sensorObject);
            _state[std::move(key)] = std::move(value);
        }
    }
}

void TerminusHandler::parseAuxNamePDRs(const PDRList& sensorPDRs)
{
    constexpr uint8_t nullTerminator = 0;
    for (const auto& sensorPDR : sensorPDRs)
    {
        auto pdr =
            (struct pldm_sensor_auxiliary_names_pdr*)sensorPDR.data();

        if (!pdr)
        {
            std::cerr << "Failed to get Aux Name PDR" << std::endl;
            return;
        }
        auxNameKey key((uint16_t)pdr->terminus_handle,
                       (uint16_t)pdr->sensor_id);
        auxNameSensorMapping sensorNameMapping;

        const uint8_t* ptr = pdr->names;
        for ([[maybe_unused]] auto i :
             std::views::iota(0, (int)pdr->sensor_count))
        {
            const uint8_t nameStringCount = static_cast<uint8_t>(*ptr);
            auxNameList nameLists{};
            ptr += sizeof(uint8_t);
            for ([[maybe_unused]] auto j :
                 std::views::iota(0, (int)nameStringCount))
            {
                std::string nameLanguageTag(reinterpret_cast<const char*>(ptr),
                                            0, PLDM_STR_UTF_8_MAX_LEN);
                ptr += nameLanguageTag.size() + sizeof(nullTerminator);
                std::u16string u16NameString(
                    reinterpret_cast<const char16_t*>(ptr), 0,
                    PLDM_STR_UTF_16_MAX_LEN);
                ptr += (u16NameString.size() + sizeof(nullTerminator)) *
                       sizeof(uint16_t);
                std::transform(u16NameString.cbegin(), u16NameString.cend(),
                               u16NameString.begin(),
                               [](uint16_t utf16) { return be16toh(utf16); });
                std::string nameString =
                    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,
                                         char16_t>{}
                        .to_bytes(u16NameString);
                nameLists.emplace_back(
                    std::make_tuple(nameLanguageTag, nameString));
            }
            if (!nameLists.size())
            {
                continue;
            }
            sensorNameMapping.emplace_back(nameLists);
        }

        if (!sensorNameMapping.size())
        {
            std::cerr << "Failed to find Aux Name of sensor Key " << get<0>(key)
                      << ":" << get<1>(key) << "in mapping table." << std::endl;
            continue;
        }
        if (_auxNameMaps.find(key) != _auxNameMaps.end())
        {
            std::cerr << "Aux Name Key : " << get<0>(key) << ":" << get<1>(key)
                      << " existed in mapping table." << std::endl;
            continue;
        }
        _auxNameMaps[key] = sensorNameMapping;
    }
    return;
}

/** @brief Start timer to get sensor info
 */
void TerminusHandler::startSensorsPolling()
{
    readCount = 0;
    continuePollSensor = true;
    std::function<void()> pollCallback(
        std::bind(&TerminusHandler::pollSensors, this));
    std::function<void()> readCallback(
        std::bind(&TerminusHandler::readSensor, this));

    try
    {
        _timer.restart(std::chrono::milliseconds(POLL_SENSOR_TIMER_INTERVAL));
        _timer2.restart(
            std::chrono::milliseconds(SLEEP_BETWEEN_GET_SENSOR_READING));
    }
    catch (const std::exception& e)
    {
        std::cerr << "Error in sysfs polling loop" << std::endl;
        throw;
    }

    return;
}

/** @brief Stop timer to get sensor info
 */
void TerminusHandler::stopSensorsPolling()
{
    continuePollSensor = false;
    _timer.setEnabled(false);
    _timer2.setEnabled(false);
    _timer3.setEnabled(false);

    // Set sensors values to Nan and Functional property to false for FANs speeds to be driven max
    invalidateAllSensors();
}

void TerminusHandler::removeUnavailableSensor(
    const std::vector<sensor_key>& vKeys)
{
    for (const auto& key : vKeys)
    {
        if (_state.find(key) != _state.end())
        {
            _state.erase(key);
        }

        if (_sensorObjects.find(key) != _sensorObjects.end())
        {
            std::unique_ptr<PldmSensor>& sensorObj = _sensorObjects[key];
            bus.emit_object_removed(sensorObj->getSensorPath().c_str());
            _sensorObjects.erase(key);
        }

        if (_stateSensorObjects.find(key) != _stateSensorObjects.end())
        {
            std::unique_ptr<PldmStateSensor>& sensorObj =
                _stateSensorObjects[key];
            bus.emit_object_removed(sensorObj->getSensorPath().c_str());
            _stateSensorObjects.erase(key);
        }
    }
    updateSensorKeys();

    return;
}

void TerminusHandler::removeEffecterFromPollingList(
    const std::vector<sensor_key>& vKeys)
{
    for (const auto& key : vKeys)
    {
        if (_state.find(key) != _state.end())
        {
            _state.erase(key);
        }
    }
    updateSensorKeys();

    return;
}

void TerminusHandler::removeMCTPEndpoint()
{
    std::string eidObject =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/" +
        std::to_string(eid);
    std::cerr << "Removing " << eidObject << std::endl;
    try
    {
        auto method = bus.new_method_call(
            "au.com.codeconstruct.MCTP1", eidObject.c_str(),
            "au.com.codeconstruct.MCTP.Endpoint1", "Remove");
        // There is no input and no outpt for Remove method.
        // The MCTP endpoint may already has been removed so we can ignore
        // error.
        [[maybe_unused]] auto reply = bus.call(method, dbusTimeout);
    }
    catch (const std::exception& e)
    {
        std::cerr << "Error in remove " << eidObject << " : " << e.what()
                  << std::endl;
    }
}

static constexpr int stopPollingThreshold = 3;
void TerminusHandler::sensorPollingTimeoutHandler()
{
    timeoutCount++;
    if (timeoutCount >= stopPollingThreshold)
    {
        stopSensorsPolling();

        // Remove our MCTP endpoint and mctp-i2c.service will keep retry to
        // re-setup MCTP endpoint. terminus_manager will delay the erase of this
        // terminus until the same MCTP endpoint is added.
        removeMCTPEndpoint();
    }
}

/** @brief Start reading the sensors info process
 */
void TerminusHandler::pollSensors()
{
    if (!isTerminusOn())
    {
        return;
    }

    if (!continuePollSensor)
    {
        return;
    }

    if (!createdDbusObject)
    {
        return;
    }

    if (pollingSensors)
    {
        std::cerr
            << std::format(
                   "Warning: eid: {}, readCount:{} Last sensor polling is not DONE.",
                   eid, readCount)
            << std::endl;
        return;
    }

#ifdef DESTROY_UNAVALIABLE_SENSOR
    if (unavailableSensorKeys.size())
    {
        removeUnavailableSensor(std::move(unavailableSensorKeys));
        unavailableSensorKeys.clear();
    }
#endif

    this->sensorKey = sensorKeys.begin();
    pollingSensors = true;
    readCount++;

    return;
}

/** @brief Start reading the sensors info process
 */
void TerminusHandler::readSensor()
{
    if (!createdDbusObject)
    {
        return;
    }

    if (!continuePollSensor)
    {
        return;
    }

    if (!pollingSensors)
    {
        return;
    }

    if (sendingPldmCommand)
    {
        return;
    }

    if (this->sensorKey == sensorKeys.begin() && debugPollSensor)
    {
        startTime = std::chrono::system_clock::now();
        std::cerr << std::format("[tid:{} {}] Start new pollSensor at {}\n",
                                 devInfo.tid, readCount,
                                 getCurrentSystemTime());
        /* Stop print polling debug after 50 rounds */
        if (readCount > 50)
        {
            debugPollSensor = false;
        }
    }

    if (this->sensorKey != sensorKeys.end())
    {
        getSensorReading(get<1>(*(this->sensorKey)),
                         get<2>(*(this->sensorKey)));
    }
    else
    {
        pollingSensors = false;

        if (debugPollSensor)
        {
            std::chrono::duration<double> elapsed =
                std::chrono::system_clock::now() - startTime;
            std::cerr << std::format("[tid:{} {}] Finish one pollsensor round"
                                     " for {} sensors after {} at {}\n",
                                     devInfo.tid, readCount, sensorKeys.size(),
                                     elapsed, getCurrentSystemTime());
        }
    }

    return;
}

bool verifySensorFunctionalStatus(const uint8_t& pdrType,
                                  const uint8_t& operationState)
{
    if (pdrType == PLDM_COMPACT_NUMERIC_SENSOR_PDR ||
        pdrType == PLDM_NUMERIC_SENSOR_PDR)
    {
        /* enabled */
        if (operationState != PLDM_SENSOR_ENABLED)
        {
            return false;
        }
    }
    else if (pdrType == PLDM_NUMERIC_EFFECTER_PDR)
    {
        /* enabled-updatePending, enabled-noUpdatePending */
        if ((operationState != EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING) &&
            (operationState != EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING))
        {
            return false;
        }
    }
    return true;
}

bool verifySensorAvailableStatus(const uint8_t& pdrType,
                                  const uint8_t& operationState)
{
    if (pdrType == PLDM_COMPACT_NUMERIC_SENSOR_PDR  ||
        pdrType == PLDM_NUMERIC_SENSOR_PDR)
    {
        /* unavailable */
        if (operationState == PLDM_SENSOR_UNAVAILABLE)
        {
            return false;
        }
    }
    else if (pdrType == PLDM_NUMERIC_EFFECTER_PDR)
    {
        /* unavailable */
        if (operationState == EFFECTER_OPER_STATE_UNAVAILABLE)
        {
            return false;
        }
    }
    return true;
}

void TerminusHandler::processStateSensorReading(mctp_eid_t,
                                                const pldm_msg* response,
                                                size_t respMsgLen)
{
    uint8_t eid = std::get<0>(*(this->sensorKey));
    uint16_t sid = std::get<1>(*(this->sensorKey));
    if (response == nullptr || !respMsgLen)
    {

        std::cerr << "Failed to receive response for the GetStateSensorReading"
                  << " command of eid:sensor " << unsigned(eid) << ":" << sid
                  << std::endl;
        pldm::flightrecorder::FlightRecorder::GetInstance().increaseError(eid);
        pldm::flightrecorder::FlightRecorder::GetInstance().printEidHistory(eid);

        /* Go to next sensor */
        this->sensorKey++;
        sendingPldmCommand = false;
        sensorPollingTimeoutHandler();
        return;
    }

    timeoutCount = 0;

    int rc = PLDM_ERROR;
    uint8_t cc = 0;
    get_sensor_state_field fields[8]{};
    uint8_t compositeSensorCount = 0;
    rc = decode_get_state_sensor_readings_resp(response, respMsgLen, &cc,
                                               &compositeSensorCount, fields);

    std::unique_ptr<PldmStateSensor>& sensorObj =
        _stateSensorObjects[*(this->sensorKey)];
    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode get sensor value: "
                  << "rc=" << unsigned(rc) << ",cc=" << unsigned(cc) << " "
                  << unsigned(eid) << ":" << sid << std::endl;
    }
    else
    {
        sensorObj->updateStateReading(compositeSensorCount, fields);
    }
    this->sensorKey++;
    sendingPldmCommand = false;
    return;
}

void TerminusHandler::invalidateAllSensors()
{
    // Numeric sensors
    for (auto& entry : _sensorObjects)
    {
        entry.second->setFunctionalStatus(false);
        entry.second->updateValue(std::numeric_limits<double>::quiet_NaN());
    }

    // State sensors
    for (auto& entry : _stateSensorObjects)
    {
        entry.second->invalidateStateSensor();
    }
}

/** @brief Callback function to process the response data after send the
 * getSensorReading request thru PLDM
 */
void TerminusHandler::processSensorReading(mctp_eid_t, const pldm_msg* response,
                                           size_t respMsgLen)
{
    if (response == nullptr || !respMsgLen)
    {
        auto sid = std::get<1>(*(this->sensorKey));
        std::cerr << "Failed to receive response for the GetSensorReading"
                  << " command of eid:sensor " << unsigned(eid) << ":" << sid
                  << std::endl;
        pldm::flightrecorder::FlightRecorder::GetInstance().increaseError(eid);
        pldm::flightrecorder::FlightRecorder::GetInstance().printEidHistory(
            eid);

        std::unique_ptr<PldmSensor>& sensorObj =
            _sensorObjects[*(this->sensorKey)];
        sensorObj->updateValue(std::numeric_limits<double>::quiet_NaN());
        sensorObj->setFunctionalStatus(false);
        /* Go to next sensor */
        this->sensorKey++;
        sensorPollingTimeoutHandler();
    }
    else
    {
        timeoutCount = 0;
        int rc = PLDM_ERROR;
        uint8_t pdr_type = std::get<2>(*(this->sensorKey));
        union_range_field_format presentReading;
        uint8_t cc = 0;
        uint8_t dataSize = PLDM_SENSOR_DATA_SIZE_SINT32;
        uint8_t operationalState = PLDM_SENSOR_ENABLED;
        uint8_t eventMessEn;
        uint8_t presentState;
        uint8_t previousState;
        uint8_t eventState;
        union_range_field_format pendingValue;
        SensorValueType sensorValue =
                std::numeric_limits<double>::quiet_NaN();

        if (pdr_type == PLDM_COMPACT_NUMERIC_SENSOR_PDR ||
            pdr_type == PLDM_NUMERIC_SENSOR_PDR)
        {
            rc = decode_get_sensor_reading_resp(
                response, respMsgLen, &cc, &dataSize, &operationalState,
                &eventMessEn, &presentState, &previousState, &eventState,
                reinterpret_cast<uint8_t*>(&presentReading));
        }
        else if (pdr_type == PLDM_NUMERIC_EFFECTER_PDR)
        {
            rc = decode_get_numeric_effecter_value_resp(
                response, respMsgLen, &cc, &dataSize, &operationalState,
                reinterpret_cast<uint8_t*>(&pendingValue),
                reinterpret_cast<uint8_t*>(&presentReading));
        }
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            auto sid = std::get<1>(*(this->sensorKey));
            std::cerr << "Failed to decode get sensor value: "
                    << "rc=" << unsigned(rc) << ",cc=" << unsigned(cc) << " "
                    << unsigned(eid) << ":" << sid << std::endl;
            sensorValue = std::numeric_limits<double>::quiet_NaN();
            operationalState = PLDM_SENSOR_DISABLED;
        }
        else
        {
            switch (dataSize)
            {
                case PLDM_SENSOR_DATA_SIZE_UINT8:
                    sensorValue = static_cast<double>(presentReading.value_u8);
                    break;
                case PLDM_SENSOR_DATA_SIZE_SINT8:
                    sensorValue = static_cast<double>(presentReading.value_s8);
                    break;
                case PLDM_SENSOR_DATA_SIZE_UINT16:
                    sensorValue =
                        static_cast<double>(presentReading.value_u16);
                    break;
                case PLDM_SENSOR_DATA_SIZE_SINT16:
                    sensorValue =
                        static_cast<double>(presentReading.value_s16);
                    break;
                case PLDM_SENSOR_DATA_SIZE_UINT32:
                    sensorValue =
                        static_cast<double>(presentReading.value_u32);
                    break;
                case PLDM_SENSOR_DATA_SIZE_SINT32:
                    sensorValue =
                        static_cast<double>(presentReading.value_s32);
                    break;
                default:
                    sensorValue = std::numeric_limits<double>::quiet_NaN();
                    break;
            }
        }
        std::unique_ptr<PldmSensor>& sensorObj =
            _sensorObjects[*(this->sensorKey)];
        bool functional = verifySensorFunctionalStatus(
            std::get<2>(*(this->sensorKey)), operationalState);
        [[maybe_unused]] bool available = verifySensorAvailableStatus(
            std::get<2>(*(this->sensorKey)), operationalState);

#ifdef DESTROY_UNAVALIABLE_SENSOR
        /* the CompactNumericSensor is unavailable */
        if (!available)
        {
            unavailableSensorKeys.push_back(*(this->sensorKey));
        }
#endif

        if (sensorObj)
        {
            /* unavailable */
            if (!functional)
            {
                sensorValue = std::numeric_limits<double>::quiet_NaN();
            }
            sensorObj->setFunctionalStatus(functional);
            sensorObj->updateValue(sensorValue);
        }
        this->sensorKey++;
    }
    sendingPldmCommand = false;
    return;
}

/** @brief Send the getSensorReading request to get sensor info
 */
void TerminusHandler::getSensorReading(uint16_t sensor_id, uint8_t pdr_type)
{
    sendingPldmCommand = true;
    uint8_t req_byte = PLDM_GET_SENSOR_READING_REQ_BYTES;
    if (pdr_type == PLDM_NUMERIC_EFFECTER_PDR)
    {
        req_byte = PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES;
    }
    else if (pdr_type == PLDM_STATE_SENSOR_PDR)
    {
        req_byte = PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES;
    }

    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + req_byte);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    uint8_t rearmEventState = 0;
    auto instanceId = instanceIdDb.next(eid);

    int rc = PLDM_ERROR;
    if (pdr_type == PLDM_COMPACT_NUMERIC_SENSOR_PDR ||
        pdr_type == PLDM_NUMERIC_SENSOR_PDR)
    {
        rc = encode_get_sensor_reading_req(instanceId, sensor_id,
                                           rearmEventState, request);
    }
    else if (pdr_type == PLDM_NUMERIC_EFFECTER_PDR)
    {
        rc = encode_get_numeric_effecter_value_req(instanceId, sensor_id,
                                                   request);
    }
    else if (pdr_type == PLDM_STATE_SENSOR_PDR)
    {
        bitfield8_t sensor_rearm{0};
        rc = encode_get_state_sensor_readings_req(instanceId, sensor_id,
                                                  sensor_rearm, 0, request);
    }

    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to reading sensor/effecter, rc = " << rc
                  << std::endl;
        return;
    }

    uint8_t cmd = PLDM_GET_SENSOR_READING;
    if (pdr_type == PLDM_STATE_SENSOR_PDR)
    {
        // We use a different callback to process state sensor reading
        cmd = PLDM_GET_STATE_SENSOR_READINGS;
        rc = handler->registerRequest(
            eid, instanceId, PLDM_PLATFORM, cmd, std::move(requestMsg),
            std::move(std::bind_front(
                &TerminusHandler::processStateSensorReading, this)));
        if (rc)
        {
            std::cerr << "Failed to send reading state sensor request"
                      << std::endl;
        }
        return;
    }
    else
    {
        if (pdr_type == PLDM_COMPACT_NUMERIC_SENSOR_PDR ||
            pdr_type == PLDM_NUMERIC_SENSOR_PDR)
        {
            cmd = PLDM_GET_SENSOR_READING;
        }
        else if (pdr_type == PLDM_NUMERIC_EFFECTER_PDR)
        {
            cmd = PLDM_GET_NUMERIC_EFFECTER_VALUE;
        }

        rc = handler->registerRequest(
            eid, instanceId, PLDM_PLATFORM, cmd, std::move(requestMsg),
            std::move(
                std::bind_front(&TerminusHandler::processSensorReading, this)));
        if (rc)
        {
            std::cerr
                << "Failed to send reading numeric sensor/effecter request"
                << std::endl;
        }
        return;
    }
}

void TerminusHandler::updateSensorKeys()
{
    for(auto it = _state.begin(); it != _state.end(); ++it) {
        sensorKeys.push_back(it->first);
    }
}

void TerminusHandler::stopTerminusHandler()
{
    stopTerminusPolling = true;
    stopSensorsPolling();
}

void TerminusHandler::addEventMsg(uint8_t tid, uint8_t eventId,
                                  uint8_t eventType, uint8_t eventClass)
{
    if (tid != devInfo.tid)
        return;
#ifdef AMPERE
    if (eventId == 200)
    {
        stopSensorsPolling();
    }
#endif
    if (eventDataHndl)
        eventDataHndl->addEventMsg(eventId, eventType, eventClass);
#ifdef AMPERE
    if (eventId == 200)
    {
        // Stop hang dectection service
        if (system("systemctl stop ampere-sysfw-hang-handler.service"))
        {
            error("Failed to call stop hand-detection service");
        }

    }
#endif
}

requester::Coroutine TerminusHandler::setNumericEffecterValue(uint16_t effecterId,
                                uint8_t effecterDataSize, const uint8_t* effecterValue)
{
    uint8_t instanceId = instanceIdDb.next(eid);

    Request requestMsg(sizeof(pldm_msg_hdr) + PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

    size_t payloadLength = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
    if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
        effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
    {
        payloadLength = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
    }
    if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
        effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
    {
        payloadLength = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
    }

    auto rc = encode_set_numeric_effecter_value_req(instanceId, effecterId, effecterDataSize, effecterValue, request,
                                        payloadLength);
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb.free(eid, instanceId);
        std::cerr << "Failed to set numeric effecter value, rc = " << rc
                << std::endl;
        co_return rc;
    }

    Response responseMsg{};
    rc = co_await requester::sendRecvPldmMsg(*handler, eid, requestMsg,
                                             responseMsg);
    if (rc)
    {
        std::cerr << "Failed to send sendRecvPldmMsg, EID=" << unsigned(eid)
                  << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_PLATFORM)
                  << ", cmd= " << unsigned(PLDM_SET_NUMERIC_EFFECTER_VALUE)
                  << ", rc=" << rc << std::endl;
        ;
        co_return rc;
    }

    uint8_t cc = 0;
    payloadLength = responseMsg.size() - sizeof(struct pldm_msg_hdr);
    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
    if (response == nullptr || !payloadLength)
    {
        std::cerr << "No response received for sendRecvPldmMsg, EID="
                  << unsigned(eid) << ", instanceId=" << unsigned(instanceId)
                  << ", type=" << unsigned(PLDM_PLATFORM)
                  << ", cmd= " << unsigned(PLDM_SET_NUMERIC_EFFECTER_VALUE)
                  << ", rc=" << rc << std::endl;
        ;
        co_return rc;
    }

    rc = decode_set_numeric_effecter_value_resp(response, payloadLength, &cc);

    if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
    {
        std::cerr << "Failed to decode_set_numeric_effecter_value_resp"
                  << ", rc=" << unsigned(rc) << " cc=" << unsigned(cc)
                  << std::endl;
        co_return cc;
    }

    co_return cc;
}

/**
 *  @brief Start waiting for MPro recovery from impactless update.
 *  @details MPro's state is read by executing ampere_request_mpro_state script.
 *  If FW_BOOT_OK asserts within 60s, wait for MCTP interface. If MCTP interface
 *  from MPro is ready within 60s, restart sensor and event polling and hang
 *  detection service. Otherwise, do nothing.
 */
void TerminusHandler::waitForMProRecovery()
{
    std::string socket(&eidToName.second[1], 1);
    std::string command = "/usr/sbin/ampere_request_mpro_state.sh";

    if (!std::filesystem::exists(command))
    {
        error("IMPACTLESS UPDATE: Script to wait for MPro recovery does not exist");
        return;
    }
    command += " " + socket + " ";
    MProState stateRequest;
    switch (mProState)
    {
        case MProState::MProQuiesce: /* MPro is in quiesce mode, wait for FW_BOOT_OK to deassert.
                                        Request to read FW_BOOT_OK state */
            stateRequest  = MProState::MProDown;
            command += "fwboot";
            break;
        case MProState::MProDown: /* Request to read FW_BOOT_OK state */
            stateRequest  = MProState::MProUp;
            command += "fwboot";
            break;
        case MProState::MProUp: /* Request to read MCTP interface state */
            stateRequest  = MProState::MCTPReady;
            command += "mctpinf";
            break;
        case MProState::MCTPReady: /* Temporarily: MPro has recovered - Return */
            _timer4.setEnabled(false);
            return;
        case MProState::MProReady: /* MPro has recovered - Return */
            _timer4.setEnabled(false);
            return;
        default:
            error("IMPACTLESS UPDATE: Invalid Mpro State Request");
            _timer4.setEnabled(false);
            return;
    }

    std::stringstream strStream;
    std::string description = "IMPACTLESS UPDATE: ";

    std::string status = exec(command.c_str());
    if (status.find("0") != std::string::npos) /* MPro's requested status is on */
    {
        if (stateRequest == MProState::MProDown)
        {
            if (fwUpdateFailed)
            {
                // MC State returns Impactless Update has failed,
                // resume operation
                fwUpdateFailed = false;
                mProState = MProState::MProReady;
                _timer4.setEnabled(false);
                restartSensorAndEventPolling();
                return;
            }
            // else: wait for FW_BOOT_OK to deassert
        }
        else if (stateRequest == MProState::MProUp)
        {
            mProState = stateRequest;
            countNum = 0;

            strStream << "TID " << unsigned(devInfo.tid) << " - FW_BOOT_OK asserted";

            description += strStream.str();
            if (!description.empty())
            {
                std::string REDFISH_MESSAGE_ID = "OpenBMC.0.1.AmpereEvent";

                sd_journal_send("MESSAGE=%s", description.c_str(),
                                "REDFISH_MESSAGE_ID=%s",
                                REDFISH_MESSAGE_ID.c_str(),
                                "REDFISH_MESSAGE_ARGS=%s",
                                description.c_str(), NULL);
            }
        }
        else if (stateRequest == MProState::MCTPReady)
        {
            // TODO [Chau Ly]: In the future, might wait some seconds
            // after MTCP interface is ready before resuming actions to MPro.
            mProState = stateRequest;
            mProState = MProState::MProReady;

            strStream << "TID " << unsigned(devInfo.tid) << " - MPro MCTP Interface is ready";

            description += strStream.str();
            if (!description.empty())
            {
                std::string REDFISH_MESSAGE_ID = "OpenBMC.0.1.AmpereEvent";

                sd_journal_send("MESSAGE=%s", description.c_str(),
                                "REDFISH_MESSAGE_ID=%s",
                                REDFISH_MESSAGE_ID.c_str(),
                                "REDFISH_MESSAGE_ARGS=%s",
                                description.c_str(), NULL);
            }
            _timer4.setEnabled(false);
            restartSensorAndEventPolling();
            return;
        }
    }
    else /* MPro's requested status is not on */
    {
        if (stateRequest == MProState::MProDown) /* FW_BOOT_OK has deasserted */
        {
            strStream << "TID " << unsigned(devInfo.tid) << " - FW_BOOT_OK desserted";
            description += strStream.str();
            if (!description.empty())
            {
                std::string REDFISH_MESSAGE_ID = "OpenBMC.0.1.AmpereEvent";

                sd_journal_send("MESSAGE=%s", description.c_str(),
                                "REDFISH_MESSAGE_ID=%s",
                                REDFISH_MESSAGE_ID.c_str(),
                                "REDFISH_MESSAGE_ARGS=%s",
                                description.c_str(), NULL);
            }
            mProState = stateRequest;
        }
        else
        {
            if (countNum >= (uint16_t)(IMPACTLESS_UPDATE_MPRO_RECOVERY_TIMEOUT_MS/IMPACTLESS_UPDATE_TIMER_INTERVAL_MS))
            {
                strStream << "TID " << unsigned(devInfo.tid) << " - Timeout waiting for MPro recovery";

                description += strStream.str();
                if (!description.empty())
                {
                    std::string REDFISH_MESSAGE_ID = "OpenBMC.0.1.AmpereCritical";

                    sd_journal_send("MESSAGE=%s", description.c_str(),
                                    "REDFISH_MESSAGE_ID=%s",
                                    REDFISH_MESSAGE_ID.c_str(),
                                    "REDFISH_MESSAGE_ARGS=%s",
                                    description.c_str(), NULL);
                }
                _timer4.setEnabled(false);
                return;
            }
            countNum++;
        }
    }
    _timer4.restartOnce(std::chrono::milliseconds(IMPACTLESS_UPDATE_TIMER_INTERVAL_MS)); //100ms
    return;
}

/**
 * @brief Wait to retrieve normal operation after impactless update.
 * @details Acknowledge impactless firmware update to MPro by
 * setting value to effecter MC Control to MPro. From now,
 * start a timer to wait for MPro recovery by watching FW_BOOT_OK GPIO
 * assertion and MCTP Interface from MPro.
 */
requester::Coroutine TerminusHandler::waitForImpactlessUpdateRecovery()
{
    // Acknowledgement of firmware update
    /*
    *  Bit 31:9   |  Reserved
    *  Bit 8      |  Acknowledgement of firmware update
    *  Bit 7:0    |  1 - Enabled (default); 3 - Shutdown (All MCs are halted).
    */
    uint32_t MCControlEffecterValue = (0x00000001 | 0x00000100);
    uint8_t* valuePtr = (uint8_t*)&MCControlEffecterValue;
    auto rc = co_await setNumericEffecterValue(MCControlEffecterID, PLDM_EFFECTER_DATA_SIZE_UINT32, valuePtr);

    if (rc != PLDM_SUCCESS)
    {
        // [Chau Ly] Should we restart everything immediately???
        restartSensorAndEventPolling();
        std::cerr << "IMPACTLESS UPDATE: Failed to acknowledge impactless update\n";
        co_return rc;
    }

    std::stringstream strStream;
    std::string description = "";
    description += "IMPACTLESS UPDATE: ";

    strStream << "TID " << unsigned(devInfo.tid) << " - BMC Acknowledged";

    description += strStream.str();
    if (!description.empty())
    {
        std::string REDFISH_MESSAGE_ID = "OpenBMC.0.1.AmpereEvent";

        sd_journal_send("MESSAGE=%s", description.c_str(),
                        "REDFISH_MESSAGE_ID=%s",
                        REDFISH_MESSAGE_ID.c_str(),
                        "REDFISH_MESSAGE_ARGS=%s",
                        description.c_str(), NULL);
    }
    mProState = MProState::MProQuiesce;
    _timer4.restartOnce(std::chrono::milliseconds(IMPACTLESS_UPDATE_TIMER_INTERVAL_MS)); //100ms
    co_return rc;
}

/**
 * @brief Start waiting for RAS polling completion to:
 * 1. Stop sensor polling
 * 2. Stop event polling
 * 3. Write to MC Control Effecter (effecterId = 254) to acknowledge host firmware update
 */
void TerminusHandler::waitForRASPollingFinished()
{
    if (!eventDataHndl)
    {
        return;
    }
    if (eventDataHndl->areBMCRASQueuesEmpty() && eventDataHndl->areMProRASQueuesEmpty())
    {
        std::cerr << "DEBUG: Polling all remaining RAS is finished after "
                  << unsigned(countNum*IMPACTLESS_UPDATE_TIMER_INTERVAL_MS/1000) << " seconds \n";
        stopSensorsPolling();
        eventDataHndl->stopEventSignalPolling();
        eventDataHndl->inQuiesceMode(false);
        countNum = 0;

        // Stop hang dectection service
        if (system("systemctl stop ampere-sysfw-hang-handler.service"))
        {
            error("Failed to call stop hand-detection service");
        }

        [[maybe_unused]] auto co = waitForImpactlessUpdateRecovery();
        return;
    }
    else
    {
        // Polling RAS is not finished within timeout
        if (countNum >= (uint16_t)(IMPACTLESS_UPDATE_FINISH_RAS_TIMEOUT_MS/IMPACTLESS_UPDATE_TIMER_INTERVAL_MS))
        {
            eventDataHndl->inQuiesceMode(false);
            countNum = 0;
            //Log to REDFISH
            std::stringstream strStream;
            std::string description = "";
            description += "IMPACTLESS UPDATE: ";

            strStream << "TID " << unsigned(devInfo.tid) << " - Quiesce mode FAILED, Polling RAS is not done within timer";

            description += strStream.str();
            if (!description.empty())
            {
                std::string REDFISH_MESSAGE_ID = "OpenBMC.0.1.AmpereEvent";

                sd_journal_send("MESSAGE=%s", description.c_str(),
                                "REDFISH_MESSAGE_ID=%s",
                                REDFISH_MESSAGE_ID.c_str(),
                                "REDFISH_MESSAGE_ARGS=%s",
                                description.c_str(), NULL);
            }
            return;
        }
        else
        {
            countNum++;
        }
    }
    _timer3.restartOnce(std::chrono::milliseconds(IMPACTLESS_UPDATE_TIMER_INTERVAL_MS)); //100ms
    return;
}

/** @brief Enter quiesce mode after polling all remaining RAS events
 *  @details Stop hang detection service, sensor and event polling
 *  after finishing polling the remaining RAS events. First, start
 *  a timer to wait for RAS polling completion.
 */
void TerminusHandler::startQuiesceMode()
{
    eventDataHndl->inQuiesceMode(true);
    _timer3.restartOnce(std::chrono::milliseconds(IMPACTLESS_UPDATE_TIMER_INTERVAL_MS)); //100ms
}

/** @brief Restart sensor and event polling
 */
void TerminusHandler::restartSensorAndEventPolling()
{
    startSensorsPolling();
    eventDataHndl->startEventSignalPolling();
    // Start hang dectection service
    if (system("systemctl start ampere-sysfw-hang-handler.service"))
    {
        error("Failed to call call stop hand-detection service");
    }
}

void TerminusHandler::createEntityAssociationMap(const PDRList& associationPDRs)
{
    for (const auto& pdr : associationPDRs)
    {
        auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>(
            const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr));
        size_t numEntities{};
        pldm_entity* entities = nullptr;

        PLDMEntity parent{entityPdr->container.entity_type,
                          entityPdr->container.entity_instance_num,
                          entityPdr->container.entity_container_id};

        // Use the libpldm C API to parse the entity assocaition PDR
        pldm_entity_association_pdr_extract(pdr.data(), pdr.size(),
                                            &numEntities, &entities);
        // The first entity is the container Entity, child starts from 1
        for (size_t i = 1; i < numEntities; i++)
        {
            PLDMEntity child{entities[i].entity_type,
                             entities[i].entity_instance_num,
                             entities[i].entity_container_id};
            // parent contains child
            entityAssociationMap[parent].insert(child);
        }
        // Free resources
        free(entities);
    }
}

void TerminusHandler::createNicAndPortInventory()
{
    for (const auto& [entity, childs] : entityAssociationMap)
    {
        if (entity.entityType != PLDM_ENTITY_NETWORK_CONTROLLER)
        {
            continue;
        }

        // Suport one chassis X multiple terminus X multiple NIC inst topology
        std::string nicName = std::format("{}_NIC_{}", terminusName, entity.instNum);
        std::string nicInventoryPath = chassisInventoryPath + "/" + nicName;
        std::shared_ptr<NicInventory> nicInventory =
            std::make_shared<NicInventory>(
                bus, entity, nicName, nicInventoryPath, chassisInventoryPath);
        entityToInventoryMap[entity] = nicInventory;

        for (const PLDMEntity& child : childs)
        {
            if (child.entityType != PLDM_ENTITY_ETHERNET)
            {
                continue;
            }

            const std::string portName = std::format("Port_{}", child.instNum);
            const std::string portInventoryPath = nicInventoryPath + "/" +
                                                  portName;
            std::shared_ptr<PortInventory> portInventory =
                std::make_shared<PortInventory>(
                    bus, child, portName, portInventoryPath, nicInventoryPath);
            entityToInventoryMap[child] = portInventory;
        }
    }
}

} // namespace terminus

} // namespace pldm
