#include "platform.hpp"

#include "common/types.hpp"
#include "common/utils.hpp"
#include "event_parser.hpp"
#include "file_lock.hpp"
#include "pdr.hpp"
#include "pdr_file.hpp"
#include "pdr_numeric_effecter.hpp"
#include "pdr_state_effecter.hpp"
#include "pdr_state_sensor.hpp"
#include "pdr_utils.hpp"
#include "platform_numeric_effecter.hpp"
#include "platform_state_effecter.hpp"
#include "platform_state_sensor.hpp"
#include "pldmd/handler.hpp"
#include "requester/handler.hpp"

#include <libpldm/entity.h>
#include <libpldm/state_set.h>
#include <sys/stat.h>
#include <unistd.h>

#include <phosphor-logging/lg2.hpp>

#include <memory>

PHOSPHOR_LOG2_USING;

using namespace pldm::utils;
using namespace pldm::responder::pdr;
using namespace pldm::responder::pdr_utils;

namespace pldm
{
namespace responder
{
namespace platform
{
using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

static const Json empty{};

constexpr const char* ihFwLockFilePath = "/tmp/ih_fw.lock";

void Handler::addDbusObjMaps(
    uint16_t id,
    std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
    TypeId typeId)
{
    if (typeId == TypeId::PLDM_SENSOR_ID)
    {
        sensorDbusObjMaps.emplace(id, dbusObj);
    }
    else
    {
        effecterDbusObjMaps.emplace(id, dbusObj);
    }
}

const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
    Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
{
    if (typeId == TypeId::PLDM_SENSOR_ID)
    {
        return sensorDbusObjMaps.at(id);
    }
    else
    {
        return effecterDbusObjMaps.at(id);
    }
}

void Handler::generate(const pldm::utils::DBusHandler* dBusIntf,
                       const std::vector<fs::path>& dir, Repo& repo)
{
    // Acquire the file lock before processing PDRs. We can pass the lock file
    // through a EM config later. We could also pass different locks based on
    // the directory. For now we are hardcoding the lock file path and using it
    // before opening any directory.
    const std::string lockFilePath = ihFwLockFilePath;
    std::unique_ptr<FileLock> lock;
    try
    {
        lock = std::make_unique<FileLock>(lockFilePath);
        info("Acquired lock on {LOCK_FILE}", "LOCK_FILE", lockFilePath);
    }
    catch (const std::runtime_error& e)
    {
        error(
            "Failed to acquire lock on {LOCK_FILE}: {ERROR}. Continuing without lock. There is a possibility of PDR config JSONs and corresponding files mismatch.",
            "LOCK_FILE", lockFilePath, "ERROR", e.what());
    }

    // Close and clear existing file info and snapshots to prevent leaks
    for (auto& [id, info] : fileIdentifierToFileInfo)
    {
        if (info.fp)
        {
            fclose(info.fp);
            info.fp = nullptr;
        }
    }
    fileIdentifierToFileInfo.clear();
    recordHandleToFileInfo.clear();

    for (auto& [tid, tidMap] : tidFileSnapshots)
    {
        for (auto& [id, info] : tidMap)
        {
            if (info.fp)
            {
                fclose(info.fp);
                info.fp = nullptr;
            }
        }
    }
    tidFileSnapshots.clear();

    // A map of PDR type to a lambda that handles creation of that PDR type.
    // The lambda essentially would parse the platform specific PDR JSONs to
    // generate the PDR structures. This function iterates through the map to
    // invoke all lambdas, so that all PDR types can be created.

    const std::map<Type, generatePDR> generateHandlers = {
        {PLDM_STATE_EFFECTER_PDR,
         [this](const DBusHandler& dBusIntf, const auto& json,
                RepoInterface& repo) {
             pdr_state_effecter::generateStateEffecterPDR<
                 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
                                                    repo);
         }},
        {PLDM_NUMERIC_EFFECTER_PDR,
         [this](const DBusHandler& dBusIntf, const auto& json,
                RepoInterface& repo) {
             pdr_numeric_effecter::generateNumericEffecterPDR<
                 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
                                                    repo);
         }},
        {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf,
                                       const auto& json, RepoInterface& repo) {
             pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler,
                                                      Handler>(dBusIntf, json,
                                                               *this, repo);
         }}};

    Type pdrType{};
    for (const auto& directory : dir)
    {
        if (!fs::exists(directory))
        {
            error("PDR config directory '{PATH}' does not exist", "PATH",
                  directory);
            continue;
        }

        try
        {
            for (const auto& dirEntry : fs::directory_iterator(directory))
            {
                try
                {
                    if (fs::is_regular_file(dirEntry.path()) &&
                        dirEntry.path().extension() == ".json")
                    {
                        std::string configFilePath = dirEntry.path().string();
                        struct timespec config_last_modified{};
                        struct stat configStat;
                        if (stat(configFilePath.c_str(), &configStat) == 0)
                        {
                            config_last_modified = configStat.st_mtim;
                        }
                        else
                        {
                            error("Failed to stat config file {PATH}", "PATH",
                                  configFilePath);
                        }

                        auto json = readJson(configFilePath);
                        if (!json.empty())
                        {
                            auto filePdrs =
                                json.value("fileDescriptorPDRs", empty);
                            for (const auto& filePdrEntries : filePdrs)
                            {
                                pdr_file::generateFileDescriptorPDR(
                                    filePdrEntries, configFilePath,
                                    config_last_modified,
                                    fileIdentifierToFileInfo,
                                    recordHandleToFileInfo, repo);
                            }

                            auto effecterPDRs =
                                json.value("effecterPDRs", empty);
                            for (const auto& effecter : effecterPDRs)
                            {
                                pdrType = effecter.value("pdrType", 0);
                                if (dBusIntf)
                                {
                                    generateHandlers.at(
                                        pdrType)(*dBusIntf, effecter, repo);
                                }
                            }

                            auto sensorPDRs = json.value("sensorPDRs", empty);
                            for (const auto& sensor : sensorPDRs)
                            {
                                pdrType = sensor.value("pdrType", 0);
                                if (dBusIntf)
                                {
                                    generateHandlers.at(
                                        pdrType)(*dBusIntf, sensor, repo);
                                }
                            }
                        }
                    }
                }
                catch (const InternalFailure& e)
                {
                    error(
                        "PDR config directory '{PATH}' does not exist or empty for '{TYPE}' pdr, error - {ERROR}",
                        "PATH", dirEntry.path(), "TYPE", pdrType, "ERROR", e);
                }
                catch (const Json::exception& e)
                {
                    error(
                        "Failed to parse PDR JSON file {PATH}, error - {ERROR}",
                        "PATH", dirEntry.path(), "ERROR", e);
                    pldm::utils::reportError(
                        "xyz.openbmc_project.PLDM.Error.Generate.PDRJsonFileParseFail");
                }
                catch (const std::exception& e)
                {
                    error(
                        "Failed to parse PDR JSON file {PATH}, error - {ERROR}",
                        "PATH", dirEntry.path(), "ERROR", e);
                    pldm::utils::reportError(
                        "xyz.openbmc_project.PLDM.Error.Generate.PDRJsonFileParseFail");
                }
            }
        }
        catch (const fs::filesystem_error& e)
        {
            error(
                "Failed to iterate over PDR config directory '{PATH}', error - {ERROR}",
                "PATH", directory, "ERROR", e);
        }
    }

    // Release the lock when exiting the scope
    if (lock)
    {
        info("Released lock on {LOCK_FILE}", "LOCK_FILE", lockFilePath);
    }
}

bool Handler::isFileModified(uint16_t fileIdentifier)
{
    auto it = fileIdentifierToFileInfo.find(fileIdentifier);
    if (it == fileIdentifierToFileInfo.end())
    {
        error(
            "File identifier {FILE_ID} not found. Cannot check modification status.",
            "FILE_ID", fileIdentifier);
        return false;
    }

    const auto& fileInfo = it->second;
    struct stat fileStat;
    if (stat(fileInfo.filePath.c_str(), &fileStat) != 0)
    {
        error("Failed to stat file {FILE_PATH}", "FILE_PATH",
              fileInfo.filePath);
        // Treat as modified if stat fails, so that we attempt to refresh the
        // PDR and get a valid file pointer on next access. This is a safer
        // failure mode than treating it as unmodified, which might lead to
        // stale file pointers.
        return true;
    }

    if (fileStat.st_mtim.tv_sec > fileInfo.last_modified.tv_sec ||
        (fileStat.st_mtim.tv_sec == fileInfo.last_modified.tv_sec &&
         fileStat.st_mtim.tv_nsec > fileInfo.last_modified.tv_nsec))
    {
        info("File {FILE_PATH} (ID: {FILE_ID}) has been modified", "FILE_PATH",
             fileInfo.filePath, "FILE_ID", fileIdentifier);
        return true;
    }

    struct stat configStat;
    if (stat(fileInfo.configFilePath.c_str(), &configStat) != 0)
    {
        error("Failed to stat config file {FILE_PATH}", "FILE_PATH",
              fileInfo.configFilePath);
        return true;
    }

    if (configStat.st_mtim.tv_sec > fileInfo.config_last_modified.tv_sec ||
        (configStat.st_mtim.tv_sec == fileInfo.config_last_modified.tv_sec &&
         configStat.st_mtim.tv_nsec > fileInfo.config_last_modified.tv_nsec))
    {
        info(
            "Config file {FILE_PATH} (for File ID: {FILE_ID}) has been modified",
            "FILE_PATH", fileInfo.configFilePath, "FILE_ID", fileIdentifier);
        return true;
    }

    return false;
}

void Handler::refreshSingleFilePDR(uint16_t fileIdentifier)
{
    const std::string lockFilePath = ihFwLockFilePath;
    std::unique_ptr<FileLock> lock;
    try
    {
        lock = std::make_unique<FileLock>(lockFilePath);
        info("Acquired lock for PDR refresh on {LOCK_FILE}", "LOCK_FILE",
             lockFilePath);
    }
    catch (const std::runtime_error& e)
    {
        error(
            "Failed to acquire lock for PDR refresh: {ERROR}. Continuing PDR refresh without lock. There is a possibility of PDR config JSONs and corresponding files mismatch.",
            "ERROR", e.what());
    }

    auto it = fileIdentifierToFileInfo.find(fileIdentifier);
    if (it == fileIdentifierToFileInfo.end())
    {
        error("refreshSingleFilePDR: File ID {FID} not found", "FID",
              fileIdentifier);
        return;
    }
    pdr_file::FileInfo staleFileInfo = it->second;

    if (staleFileInfo.fp)
    {
        fclose(staleFileInfo.fp);
    }

    recordHandleToFileInfo.erase(staleFileInfo.recordHandle);
    fileIdentifierToFileInfo.erase(it);

    int del_rc = pldm_pdr_delete_by_record_handle(
        pdrRepo.getPdr(), staleFileInfo.recordHandle, false);
    if (del_rc != 0)
    {
        error("Failed to delete old PDR record {RH} for File ID {FID}, rc={RC}",
              "RH", staleFileInfo.recordHandle, "FID", fileIdentifier, "RC",
              del_rc);
        return;
    }

    nlohmann::json newFileEntry = staleFileInfo.fileJsonEntry;
    struct timespec config_last_modified = staleFileInfo.config_last_modified;

    struct stat configStat;
    if (stat(staleFileInfo.configFilePath.c_str(), &configStat) == 0)
    {
        config_last_modified = configStat.st_mtim;
        auto staleFileNameIt = staleFileInfo.fileJsonEntry.find("FileName");
        if (staleFileNameIt != staleFileInfo.fileJsonEntry.end() &&
            staleFileNameIt->is_string())
        {
            pdr_file::getFileEntryFromConfig(
                staleFileInfo.configFilePath,
                staleFileNameIt->get<std::string>(), newFileEntry);
        }
    }
    else
    {
        error("Failed to stat config file {PATH} during refresh", "PATH",
              staleFileInfo.configFilePath);
    }

    uint32_t recordHandle = staleFileInfo.recordHandle;
    if (!pdr_file::generateSingleFilePDR(
            newFileEntry, staleFileInfo.directoryPath, staleFileInfo.entityType,
            staleFileInfo.containerId, staleFileInfo.configFilePath,
            config_last_modified, fileIdentifierToFileInfo,
            recordHandleToFileInfo, pdrRepo, &recordHandle))
    {
        error("Failed to regenerate PDR for File ID {FID}", "FID",
              fileIdentifier);
        return;
    }

    if (recordHandle != staleFileInfo.recordHandle)
    {
        error(
            "PDR for File ID {FID} re-added with handle {NEW}, expected {OLD}",
            "FID", fileIdentifier, "NEW", recordHandle, "OLD",
            staleFileInfo.recordHandle);
        return;
    }

    info("Successfully refreshed PDR for File ID {FID}", "FID", fileIdentifier);
}

bool Handler::createFileSnapshot(pldm_tid_t tid, uint32_t recordHandle)
{
    pdr_utils::PdrEntry pdrEntry{};
    uint32_t recordHandleForSnapshot = recordHandle;
    // If record handle is 0, it means the requester is asking for the first
    // record.
    if (recordHandleForSnapshot == 0)
    {
        const pldm_pdr_record* firstRecord = pdrRepo.getFirstRecord(pdrEntry);
        if (firstRecord == nullptr)
        {
            error(
                "No records found in PDR repository when trying to create file snapshot for TID {TID}",
                "TID", tid);
            return false;
        }
        recordHandleForSnapshot = pdrRepo.getRecordHandle(firstRecord);
    }

    auto fileInforIter = recordHandleToFileInfo.find(recordHandleForSnapshot);
    if (fileInforIter == recordHandleToFileInfo.end())
    {
        error(
            "Record handle {RECORD_HANDLE} not found in recordHandleToFileInfo. Cannot create file snapshot.",
            "RECORD_HANDLE", recordHandleForSnapshot);
        return false;
    }

    uint16_t fileIdentifier = fileInforIter->second.fileIdentifier;
    uint16_t oldFileIdentifier = fileIdentifier;
    pdr_file::FileInfo snapshotFileInfo = fileInforIter->second;

    if (isFileModified(fileIdentifier))
    {
        info("File ID {FID} modified, refreshing its PDR...", "FID",
             fileIdentifier);
        refreshSingleFilePDR(fileIdentifier);
        auto newFileIter = recordHandleToFileInfo.find(recordHandleForSnapshot);
        if (newFileIter == recordHandleToFileInfo.end())
        {
            error(
                "Record handle {RH} not found in recordHandleToFileInfo after PDR refresh.",
                "RH", recordHandleForSnapshot);
            return false;
        }
        snapshotFileInfo = newFileIter->second;
        fileIdentifier = snapshotFileInfo.fileIdentifier;
    }

    // Clean up any previous snapshot for this TID and both old and new File IDs
    auto& tidMap = tidFileSnapshots[tid];

    std::vector<uint16_t> idsToClean = {fileIdentifier};
    if (oldFileIdentifier != fileIdentifier)
    {
        idsToClean.push_back(oldFileIdentifier);
    }

    for (uint16_t id : idsToClean)
    {
        auto snapIt = tidMap.find(id);
        if (snapIt != tidMap.end())
        {
            if (snapIt->second.fp)
            {
                info("Closing stale snapshot for TID {TID} File ID {FILE_ID}",
                     "TID", tid, "FILE_ID", id);
                fclose(snapIt->second.fp);
            }
            tidMap.erase(snapIt);
        }
    }

    // Calculate total snapshots across all TIDs
    size_t totalSnapshots = 0;
    for (const auto& [currentTid, currentTidMap] : tidFileSnapshots)
    {
        totalSnapshots += currentTidMap.size();
    }

    auto now = std::chrono::steady_clock::now();

    if (totalSnapshots >= maxSnapshots)
    {
        if (!ejectStaleSnapshot(now))
        {
            error(
                "Cannot create snapshot for TID {TID}. Maximum capacity ({LIMIT}) reached and no stale snapshots could be ejected.",
                "TID", tid, "LIMIT", maxSnapshots);
            return false;
        }
    }

    FILE* newFp = nullptr;
    uint32_t fileSize = 0;
    if (this->getFilePointer(fileIdentifier, &newFp, &fileSize) != 0)
    {
        error(
            "Failed to get file pointer for snapshot for TID {TID} File ID {FILE_ID}",
            "TID", tid, "FILE_ID", fileIdentifier);
        return false;
    }

    snapshotFileInfo.fp = newFp;
    snapshotFileInfo.fileSize = fileSize;
    snapshotFileInfo.snapshotCreationTime = now;
    tidMap[fileIdentifier] = snapshotFileInfo;
    info("Created snapshot for TID {TID} File ID {FILE_ID}", "TID", tid,
         "FILE_ID", fileIdentifier);
    return true;
}

bool Handler::ejectStaleSnapshot(
    const std::chrono::steady_clock::time_point& now)
{
    info(
        "Snapshot limit reached ({LIMIT}), looking for stale snapshots to eject.",
        "LIMIT", maxSnapshots);

    uint8_t oldestTid = 0;
    uint16_t oldestFileId = 0;
    std::chrono::steady_clock::duration maxAge =
        std::chrono::steady_clock::duration::zero();
    bool foundStale = false;

    for (const auto& [currentTid, currentTidMap] : tidFileSnapshots)
    {
        for (const auto& [currentFileId, info] : currentTidMap)
        {
            auto age = now - info.snapshotCreationTime;
            if (age > snapshotTimeout && age > maxAge)
            {
                maxAge = age;
                oldestTid = currentTid;
                oldestFileId = currentFileId;
                foundStale = true;
            }
        }
    }

    if (!foundStale)
    {
        return false;
    }

    auto& staleMap = tidFileSnapshots[oldestTid];
    auto staleIt = staleMap.find(oldestFileId);
    if (staleIt != staleMap.end())
    {
        if (staleIt->second.fp)
        {
            info(
                "Ejecting stale snapshot for TID {TID} File ID {FILE_ID} due to capacity constraints.",
                "TID", oldestTid, "FILE_ID", oldestFileId);
            fclose(staleIt->second.fp);
        }
        staleMap.erase(staleIt);
        return true;
    }
    return false;
}

bool Handler::isSnapshotValid(uint8_t tid, uint16_t fileIdentifier) const
{
    auto tidIt = tidFileSnapshots.find(tid);
    if (tidIt == tidFileSnapshots.end())
    {
        return false;
    }

    auto fileIt = tidIt->second.find(fileIdentifier);
    if (fileIt == tidIt->second.end())
    {
        return false;
    }

    auto now = std::chrono::steady_clock::now();
    if ((now - fileIt->second.snapshotCreationTime) > snapshotTimeout)
    {
        return false;
    }

    return true;
}

Response Handler::getPDR(pldm_tid_t tid, const pldm_msg* request,
                         size_t payloadLength)
{
    if (oemPlatformHandler)
    {
        auto rc = oemPlatformHandler->checkBMCState();
        if (rc != PLDM_SUCCESS)
        {
            return ccOnlyResponse(request, PLDM_ERROR_NOT_READY);
        }
    }

    // Build FRU table if not built, since entity association PDR's
    // are built when the FRU table is constructed.
    if (fruHandler)
    {
        fruHandler->buildFRUTable();
    }

    if (!pdrCreated)
    {
#ifdef GENERATE_TERMINUS_LOCATOR_PDR
        generateTerminusLocatorPDR(pdrRepo);
#endif
        if (platformConfigHandler)
        {
            auto systemType = platformConfigHandler->getPlatformName();
            if (systemType.has_value())
            {
                // In case of normal poweron , the system type would have been
                // already filled by entity manager when ever BMC reaches Ready
                // state. If this is not filled by time we get a getpdr request
                // we can assume that the entity manager service is not present
                // on this system & continue to build the common PDR's.
                pdrJsonsDir.push_back(pdrJsonDir / systemType.value());
            }
        }

        if (oemPlatformHandler != nullptr)
        {
            oemPlatformHandler->buildOEMPDR(pdrRepo);
        }
        generate(dBusIntf, pdrJsonsDir, pdrRepo);

        pdrCreated = true;

        if (dbusToPLDMEventHandler)
        {
            deferredGetPDREvent = std::make_unique<sdeventplus::source::Defer>(
                event,
                std::bind(std::mem_fn(&pldm::responder::platform::Handler::
                                          _processPostGetPDRActions),
                          this, std::placeholders::_1));
        }
    }

    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);

    if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
    {
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    uint32_t recordHandle{};
    uint32_t dataTransferHandle{};
    uint8_t transferOpFlag{};
    uint16_t reqSizeBytes{};
    uint16_t recordChangeNum{};

    auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
                                 &dataTransferHandle, &transferOpFlag,
                                 &reqSizeBytes, &recordChangeNum);
    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    info("GetPDR request received with RecordHandle: {RECORD_HANDLE}",
         "RECORD_HANDLE", recordHandle);

    uint16_t respSizeBytes{};
    uint8_t* recordData = nullptr;
    try
    {
        pdr_utils::PdrEntry e;
        auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
        if (record == nullptr)
        {
            return CmdHandler::ccOnlyResponse(
                request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
        }

        pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(e.data);
        if (hdr->type == PLDM_FILE_DESCRIPTOR_PDR)
        {
            if (!createFileSnapshot(tid, recordHandle))
            {
                error(
                    "Failed to create file snapshot for TID {TID} and RecordHandle {RH}",
                    "TID", tid, "RH", recordHandle);
                return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
            }
        }

        // Re-fetch the record data as createFileSnapshot might have changed it
        record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
        if (record == nullptr)
        {
            error("PDR record {RH} vanished after snapshot creation", "RH",
                  recordHandle);
            return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
        }

        if (reqSizeBytes)
        {
            respSizeBytes = e.size;
            if (respSizeBytes > reqSizeBytes)
            {
                respSizeBytes = reqSizeBytes;
            }
            recordData = e.data;
        }
        response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
                            respSizeBytes,
                        0);
        auto responsePtr = new (response.data()) pldm_msg;
        rc = encode_get_pdr_resp(
            request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
            0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
        if (rc != PLDM_SUCCESS)
        {
            return ccOnlyResponse(request, rc);
        }
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to access PDR record handle '{RECORD_HANDLE}', error - {ERROR}",
            "RECORD_HANDLE", recordHandle, "ERROR", e);
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
    }
    return response;
}

int Handler::transferSnapshotFile(uint16_t fileIdentifier, uint8_t tid,
                                  FILE** fp, uint32_t* fileSize)
{
    auto tidIt = tidFileSnapshots.find(tid);
    if (tidIt == tidFileSnapshots.end())
    {
        error("No snapshots found for TID {TID}", "TID", tid);
        return -1;
    }

    auto& tidMap = tidIt->second;
    auto fileIt = tidMap.find(fileIdentifier);
    if (fileIt == tidMap.end())
    {
        error("No snapshot found for TID {TID} File ID {FILE_ID}", "TID", tid,
              "FILE_ID", fileIdentifier);
        return -1;
    }

    // Provide the pointer to the caller
    *fp = fileIt->second.fp;
    *fileSize = fileIt->second.fileSize;

    info("Provided snapshot for TID {TID} File ID {FILE_ID}", "TID", tid,
         "FILE_ID", fileIdentifier);
    return 0;
}

Response Handler::setStateEffecterStates(const pldm_msg* request,
                                         size_t payloadLength)
{
    Response response(
        sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;
    uint16_t effecterId;
    uint8_t compEffecterCnt;
    constexpr auto maxCompositeEffecterCnt = 8;
    std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
                                                     {0, 0});

    if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
        (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
                             sizeof(set_effecter_state_field)))
    {
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    int rc = decode_set_state_effecter_states_req(
        request, payloadLength, &effecterId, &compEffecterCnt,
        stateField.data());

    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    stateField.resize(compEffecterCnt);
    const pldm::utils::DBusHandler dBusIntf;
    uint16_t entityType{};
    uint16_t entityInstance{};
    uint16_t stateSetId{};

    if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType,
                           entityInstance, stateSetId) &&
        oemPlatformHandler != nullptr &&
        !effecterDbusObjMaps.contains(effecterId))
    {
        rc = oemPlatformHandler->oemSetStateEffecterStatesHandler(
            entityType, entityInstance, stateSetId, compEffecterCnt, stateField,
            effecterId);
    }
    else
    {
        rc = platform_state_effecter::setStateEffecterStatesHandler<
            pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
                                               stateField);
    }
    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
                                               responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::platformEventMessage(const pldm_msg* request,
                                       size_t payloadLength)
{
    uint8_t formatVersion{};
    uint8_t tid{};
    uint8_t eventClass{};
    size_t offset{};

    auto rc = decode_platform_event_message_req(
        request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    if (eventClass == PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT)
    {
        rc = PLDM_SUCCESS;
        if (oemPlatformHandler)
        {
            if (oemPlatformHandler->watchDogRunning())
            {
                oemPlatformHandler->resetWatchDogTimer();
            }
            else
            {
                oemPlatformHandler->setSurvTimer(tid, true);
            }
        }
    }
    else
    {
        try
        {
            const auto& handlers = eventHandlers.at(eventClass);
            bool oneFailedHandler = false;
            for (const auto& handler : handlers)
            {
                rc =
                    handler(request, payloadLength, formatVersion, tid, offset);
                if (rc != PLDM_SUCCESS)
                {
                    oneFailedHandler = true;
                }
            }
            if (oneFailedHandler)
            {
                return CmdHandler::ccOnlyResponse(request, rc);
            }
        }
        catch (const std::out_of_range& e)
        {
            error("Failed to handle platform event msg, error - {ERROR}",
                  "ERROR", e);
            return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
        }
    }
    Response response(
        sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;

    rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
                                            PLDM_EVENT_NO_LOGGING, responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
                         uint8_t /*formatVersion*/, uint8_t tid,
                         size_t eventDataOffset)
{
    uint16_t sensorId{};
    uint8_t eventClass{};
    size_t eventClassDataOffset{};
    auto eventData =
        reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
    auto eventDataSize = payloadLength - eventDataOffset;

    auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
                                       &eventClass, &eventClassDataOffset);
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }

    auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
                          eventDataOffset + eventClassDataOffset;
    auto eventClassDataSize =
        payloadLength - eventDataOffset - eventClassDataOffset;

    if (eventClass == PLDM_STATE_SENSOR_STATE)
    {
        uint8_t sensorOffset{};
        uint8_t eventState{};
        uint8_t previousEventState{};

        rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
                                      &sensorOffset, &eventState,
                                      &previousEventState);
        if (rc != PLDM_SUCCESS)
        {
            return PLDM_ERROR;
        }

        // Emitting state sensor event signal
        emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
                                   previousEventState);

        // If there are no HOST PDR's, there is no further action
        if (hostPDRHandler == nullptr)
        {
            return PLDM_SUCCESS;
        }

        // Handle PLDM events for which PDR is available
        SensorEntry sensorEntry{tid, sensorId};

        pldm::pdr::EntityInfo entityInfo{};
        pldm::pdr::CompositeSensorStates compositeSensorStates{};
        std::vector<pldm::pdr::StateSetId> stateSetIds{};

        try
        {
            std::tie(entityInfo, compositeSensorStates, stateSetIds) =
                hostPDRHandler->lookupSensorInfo(sensorEntry);
        }
        catch (const std::out_of_range&)
        {
            // If there is no mapping for tid, sensorId combination, try
            // PLDM_TID_RESERVED, sensorId for terminus that is yet to
            // implement TL PDR.
            try
            {
                sensorEntry.terminusID = PLDM_TID_RESERVED;
                std::tie(entityInfo, compositeSensorStates, stateSetIds) =
                    hostPDRHandler->lookupSensorInfo(sensorEntry);
            }
            // If there is no mapping for events return PLDM_SUCCESS
            catch (const std::out_of_range&)
            {
                return PLDM_SUCCESS;
            }
        }

        if (sensorOffset >= compositeSensorStates.size())
        {
            return PLDM_ERROR_INVALID_DATA;
        }

        const auto& possibleStates = compositeSensorStates[sensorOffset];
        if (!possibleStates.contains(eventState))
        {
            return PLDM_ERROR_INVALID_DATA;
        }

        const auto& [containerId, entityType, entityInstance] = entityInfo;
        events::StateSensorEntry stateSensorEntry{
            containerId,
            entityType,
            entityInstance,
            sensorOffset,
            stateSetIds[sensorOffset],
            false};
        return hostPDRHandler->handleStateSensorEvent(stateSensorEntry,
                                                      eventState);
    }
    else
    {
        return PLDM_ERROR_INVALID_DATA;
    }

    return PLDM_SUCCESS;
}

int Handler::pldmPDRRepositoryChgEvent(
    const pldm_msg* request, size_t payloadLength, uint8_t /*formatVersion*/,
    uint8_t tid, size_t eventDataOffset)
{
    uint8_t eventDataFormat{};
    uint8_t eventDataOperation{};
    uint8_t numberOfChangeRecords{};
    size_t dataOffset{};

    auto eventData =
        reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
    auto eventDataSize = payloadLength - eventDataOffset;

    auto rc = decode_pldm_pdr_repository_chg_event_data(
        eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
        &dataOffset);
    if (rc != PLDM_SUCCESS)
    {
        return rc;
    }

    PDRRecordHandles pdrRecordHandles;

    if (eventDataFormat == FORMAT_IS_PDR_TYPES)
    {
        return PLDM_ERROR_INVALID_DATA;
    }

    if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
    {
        uint8_t numberOfChangeEntries{};

        auto changeRecordData = eventData + dataOffset;
        auto changeRecordDataSize = eventDataSize - dataOffset;

        while (changeRecordDataSize)
        {
            rc = decode_pldm_pdr_repository_change_record_data(
                changeRecordData, changeRecordDataSize, &eventDataOperation,
                &numberOfChangeEntries, &dataOffset);

            if (rc != PLDM_SUCCESS)
            {
                return rc;
            }

            if (eventDataOperation == PLDM_RECORDS_MODIFIED)
            {
                hostPDRHandler->isHostPdrModified = true;
            }

            rc = getPDRRecordHandles(
                reinterpret_cast<const ChangeEntry*>(
                    changeRecordData + dataOffset),
                changeRecordDataSize - dataOffset,
                static_cast<size_t>(numberOfChangeEntries), pdrRecordHandles);

            if (rc != PLDM_SUCCESS)
            {
                error("Invalid data, no pdr handles found");
                return rc;
            }

            changeRecordData +=
                dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
            changeRecordDataSize -=
                dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
        }
    }
    if (hostPDRHandler)
    {
        // if we get a Repository change event with the eventDataFormat
        // as REFRESH_ENTIRE_REPOSITORY, then delete all the PDR's that
        // have the matched Terminus handle
        if (eventDataFormat == REFRESH_ENTIRE_REPOSITORY)
        {
            // We cannot get the Repo change event from the Terminus
            // that is not already added to the BMC repository

            for (auto it = hostPDRHandler->tlPDRInfo.cbegin();
                 it != hostPDRHandler->tlPDRInfo.cend();)
            {
                if (std::get<0>(it->second) == tid)
                {
                    pldm_pdr_remove_pdrs_by_terminus_handle(pdrRepo.getPdr(),
                                                            it->first);
                    hostPDRHandler->tlPDRInfo.erase(it++);
                }
                else
                {
                    ++it;
                }
            }
        }
        if (eventDataOperation == PLDM_RECORDS_DELETED)
        {
            hostPDRHandler->deletePDRFromRepo(std::move(pdrRecordHandles));
        }
        else
        {
            hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
        }
    }

    return PLDM_SUCCESS;
}

int Handler::getPDRRecordHandles(
    const ChangeEntry* changeEntryData, size_t changeEntryDataSize,
    size_t numberOfChangeEntries, PDRRecordHandles& pdrRecordHandles)
{
    if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    for (size_t i = 0; i < numberOfChangeEntries; i++)
    {
        pdrRecordHandles.push_back(changeEntryData[i]);
    }
    return PLDM_SUCCESS;
}

Response Handler::getNumericEffecterValue(const pldm_msg* request,
                                          size_t payloadLength)
{
    if (payloadLength != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES)
    {
        return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    uint16_t effecterId{};
    auto rc = decode_get_numeric_effecter_value_req(request, payloadLength,
                                                    &effecterId);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    const pldm::utils::DBusHandler dBusIntf;
    uint8_t effecterDataSize{};
    pldm::utils::PropertyValue dbusValue;
    std::string propertyType;
    using effecterOperationalState = uint8_t;
    using completionCode = uint8_t;

    rc = platform_numeric_effecter::getNumericEffecterData<
        pldm::utils::DBusHandler, Handler>(
        dBusIntf, *this, effecterId, effecterDataSize, propertyType, dbusValue);

    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    // Refer DSP0248_1.2.0.pdf (section 22.3, Table 48)
    // Completion Code (uint8), Effecter Data Size(uint8), Effecter Operational
    // State(uint8), PendingValue (uint8|sint8|uint16|sint16|uint32|sint32 )
    // PresentValue (uint8|sint8|uint16|sint16|uint32|sint32 )
    // Size of PendingValue and PresentValue calculated based on size is
    // provided in effecter data size
    size_t responsePayloadLength =
        sizeof(completionCode) + sizeof(effecterDataSize) +
        sizeof(effecterOperationalState) +
        getEffecterDataSize(effecterDataSize) +
        getEffecterDataSize(effecterDataSize);

    Response response(responsePayloadLength + sizeof(pldm_msg_hdr));
    auto responsePtr = new (response.data()) pldm_msg;

    rc = platform_numeric_effecter::getNumericEffecterValueHandler(
        propertyType, dbusValue, effecterDataSize, responsePtr,
        responsePayloadLength, request->hdr.instance_id);

    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to get response of GetNumericEffecterValue for effecter ID '{EFFECTERID}', response code '{RC}'.",
            "EFFECTERID", effecterId, "RC", rc);
        return ccOnlyResponse(request, rc);
    }
    return response;
}

Response Handler::setNumericEffecterValue(const pldm_msg* request,
                                          size_t payloadLength)
{
    Response response(
        sizeof(pldm_msg_hdr) + PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
    uint16_t effecterId{};
    uint8_t effecterDataSize{};
    uint8_t effecterValue[4] = {};

    if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
                             sizeof(union_effecter_data_size)) ||
        (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
    {
        return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    int rc = decode_set_numeric_effecter_value_req(
        request, payloadLength, &effecterId, &effecterDataSize, effecterValue);

    if (rc == PLDM_SUCCESS)
    {
        const pldm::utils::DBusHandler dBusIntf;
        rc = platform_numeric_effecter::setNumericEffecterValueHandler<
            pldm::utils::DBusHandler, Handler>(
            dBusIntf, *this, effecterId, effecterDataSize, effecterValue,
            sizeof(effecterValue));
    }

    return ccOnlyResponse(request, rc);
}

void Handler::generateTerminusLocatorPDR(Repo& repo)
{
    std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));

    auto pdr = new (pdrBuffer.data()) pldm_terminus_locator_pdr;

    pdr->hdr.record_handle = 0;
    pdr->hdr.version = 1;
    pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
    pdr->hdr.record_change_num = 0;
    pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
    pdr->terminus_handle = TERMINUS_HANDLE;
    pdr->validity = PLDM_TL_PDR_VALID;
    pdr->tid = TERMINUS_ID;
    pdr->container_id = 0x0;
    pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
    pdr->terminus_locator_value_size =
        sizeof(pldm_terminus_locator_type_mctp_eid);
    auto locatorValue = new (pdr->terminus_locator_value)
        pldm_terminus_locator_type_mctp_eid;
    locatorValue->eid = pldm::BmcMctpEid;

    PdrEntry pdrEntry{};
    pdrEntry.data = pdrBuffer.data();
    pdrEntry.size = pdrBuffer.size();
    repo.addRecord(pdrEntry);
    if (hostPDRHandler)
    {
        hostPDRHandler->tlPDRInfo.insert_or_assign(
            pdr->terminus_handle,
            std::make_tuple(pdr->tid, locatorValue->eid, pdr->validity));
    }
}

Response Handler::getStateSensorReadings(const pldm_msg* request,
                                         size_t payloadLength)
{
    uint16_t sensorId{};
    bitfield8_t sensorRearm{};
    uint8_t reserved{};

    if (payloadLength != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES)
    {
        return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    int rc = decode_get_state_sensor_readings_req(
        request, payloadLength, &sensorId, &sensorRearm, &reserved);

    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    // 0x01 to 0x08
    uint8_t sensorRearmCount = std::popcount(sensorRearm.byte);
    std::vector<get_sensor_state_field> stateField(sensorRearmCount);
    uint8_t comSensorCnt{};
    const pldm::utils::DBusHandler dBusIntf;

    uint16_t entityType{};
    uint16_t entityInstance{};
    uint16_t stateSetId{};
    uint16_t containerId{};

    if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt,
                         entityType, entityInstance, stateSetId, containerId) &&
        oemPlatformHandler && !sensorDbusObjMaps.contains(sensorId))
    {
        rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
            entityType, entityInstance, containerId, stateSetId, comSensorCnt,
            sensorId, stateField);
    }
    else
    {
        rc = platform_state_sensor::getStateSensorReadingsHandler<
            pldm::utils::DBusHandler, Handler>(
            dBusIntf, *this, sensorId, sensorRearmCount, comSensorCnt,
            stateField, dbusToPLDMEventHandler->getSensorCache());
    }

    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    Response response(
        sizeof(pldm_msg_hdr) + PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
        sizeof(get_sensor_state_field) * comSensorCnt);
    auto responsePtr = new (response.data()) pldm_msg;
    rc = encode_get_state_sensor_readings_resp(
        request->hdr.instance_id, rc, comSensorCnt, stateField.data(),
        responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

void Handler::_processPostGetPDRActions(sdeventplus::source::EventBase&
                                        /*source */)
{
    deferredGetPDREvent.reset();
    dbusToPLDMEventHandler->listenSensorEvent(pdrRepo, sensorDbusObjMaps);
}

bool isOemStateSensor(Handler& handler, uint16_t sensorId,
                      uint8_t sensorRearmCount, uint8_t& compSensorCnt,
                      uint16_t& entityType, uint16_t& entityInstance,
                      uint16_t& stateSetId, uint16_t& containerId)
{
    pldm_state_sensor_pdr* pdr = nullptr;

    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
        pldm_pdr_init(), pldm_pdr_destroy);
    if (!stateSensorPdrRepo)
    {
        error("Failed to instantiate state sensor PDR repository");
        return false;
    }
    Repo stateSensorPDRs(stateSensorPdrRepo.get());
    getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
    if (stateSensorPDRs.empty())
    {
        error("Failed to get record by PDR type");
        return false;
    }

    PdrEntry pdrEntry{};
    auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
    while (pdrRecord)
    {
        pdr = new (pdrEntry.data) pldm_state_sensor_pdr;
        assert(pdr != nullptr);
        if (pdr->sensor_id != sensorId)
        {
            pdr = nullptr;
            pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
            continue;
        }
        auto tmpEntityType = pdr->entity_type;
        auto tmpEntityInstance = pdr->entity_instance;
        auto tmpEntityContainerId = pdr->container_id;
        auto tmpCompSensorCnt = pdr->composite_sensor_count;
        auto tmpPossibleStates =
            reinterpret_cast<state_sensor_possible_states*>(
                pdr->possible_states);
        auto tmpStateSetId = tmpPossibleStates->state_set_id;

        if (sensorRearmCount > tmpCompSensorCnt)
        {
            error(
                "The requester sent wrong sensor rearm count '{SENSOR_REARM_COUNT}' for the sensor ID '{SENSORID}'.",
                "SENSOR_REARM_COUNT", (uint16_t)sensorRearmCount, "SENSORID",
                sensorId);
            break;
        }

        if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
             tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
            (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
             tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
        {
            entityType = tmpEntityType;
            entityInstance = tmpEntityInstance;
            stateSetId = tmpStateSetId;
            compSensorCnt = tmpCompSensorCnt;
            containerId = tmpEntityContainerId;
            return true;
        }
        else
        {
            return false;
        }
    }
    return false;
}

bool isOemStateEffecter(Handler& handler, uint16_t effecterId,
                        uint8_t compEffecterCnt, uint16_t& entityType,
                        uint16_t& entityInstance, uint16_t& stateSetId)
{
    pldm_state_effecter_pdr* pdr = nullptr;

    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
        pldm_pdr_init(), pldm_pdr_destroy);
    if (!stateEffecterPdrRepo)
    {
        error("Failed to instantiate state effecter PDR repository");
        return false;
    }
    Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
    getRepoByType(handler.getRepo(), stateEffecterPDRs,
                  PLDM_STATE_EFFECTER_PDR);
    if (stateEffecterPDRs.empty())
    {
        error("Failed to get record by PDR type");
        return false;
    }

    PdrEntry pdrEntry{};
    auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
    while (pdrRecord)
    {
        pdr = new (pdrEntry.data) pldm_state_effecter_pdr;
        assert(pdr != nullptr);
        if (pdr->effecter_id != effecterId)
        {
            pdr = nullptr;
            pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
            continue;
        }

        auto tmpEntityType = pdr->entity_type;
        auto tmpEntityInstance = pdr->entity_instance;
        auto tmpPossibleStates =
            reinterpret_cast<state_effecter_possible_states*>(
                pdr->possible_states);
        auto tmpStateSetId = tmpPossibleStates->state_set_id;

        if (compEffecterCnt > pdr->composite_effecter_count)
        {
            error(
                "The requester sent wrong composite effecter count '{COMPOSITE_EFFECTER_COUNT}' for the effecter ID '{EFFECTERID}'.",
                "COMPOSITE_EFFECTER_COUNT", compEffecterCnt, "EFFECTERID",
                effecterId);
            return false;
        }

        if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START &&
             tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) ||
            (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START &&
             tmpStateSetId < PLDM_OEM_STATE_SET_ID_END))
        {
            entityType = tmpEntityType;
            entityInstance = tmpEntityInstance;
            stateSetId = tmpStateSetId;
            return true;
        }
        else
        {
            return false;
        }
    }
    return false;
}

void Handler::setEventReceiver()
{
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) + PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
    auto request = new (requestMsg.data()) pldm_msg;
    auto instanceIdResult = instanceIdDb->next(eid);
    if (!instanceIdResult)
    {
        throw pldm::InstanceIdError(instanceIdResult.error());
    }
    auto instanceId = instanceIdResult.value();
    uint8_t eventMessageGlobalEnable =
        PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
    uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
    uint8_t eventReceiverAddressInfo = pldm::BmcMctpEid;
    uint16_t heartbeatTimer = HEARTBEAT_TIMEOUT;

    auto rc = encode_set_event_receiver_req(
        instanceId, eventMessageGlobalEnable, transportProtocolType,
        eventReceiverAddressInfo, heartbeatTimer, request);
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb->free(eid, instanceId);
        error(
            "Failed to encode set event receiver request, response code '{RC}'",
            "RC", lg2::hex, rc);
        return;
    }

    auto processSetEventReceiverResponse = [](mctp_eid_t /*eid*/,
                                              const pldm_msg* response,
                                              size_t respMsgLen) {
        if (response == nullptr || !respMsgLen)
        {
            error("Failed to receive response for setEventReceiver command");
            return;
        }

        uint8_t completionCode{};
        auto rc = decode_set_event_receiver_resp(response, respMsgLen,
                                                 &completionCode);
        if (rc || completionCode)
        {
            error(
                "Failed to decode setEventReceiver command, response code '{RC}' and completion code '{CC}'",
                "RC", rc, "CC", completionCode);
            pldm::utils::reportError(
                "xyz.openbmc_project.bmc.pldm.InternalFailure");
        }
    };
    rc = handler->registerRequest(
        eid, instanceId, PLDM_PLATFORM, PLDM_SET_EVENT_RECEIVER,
        std::move(requestMsg), std::move(processSetEventReceiverResponse));

    if (rc != PLDM_SUCCESS)
    {
        error("Failed to send the setEventReceiver request");
    }

    if (oemPlatformHandler)
    {
        oemPlatformHandler->countSetEventReceiver();
        oemPlatformHandler->checkAndDisableWatchDog();
    }
}

void Handler::sendPDRRepositoryChgEventbyPDRHandles(
    const std::vector<ChangeEntry>& pdrRecordHandles,
    const std::vector<uint8_t>& eventDataOps)
{
    uint8_t eventDataFormat = FORMAT_IS_PDR_HANDLES;
    std::vector<uint8_t> numsOfChangeEntries(1);
    std::vector<std::vector<ChangeEntry>> changeEntries(
        numsOfChangeEntries.size());
    for (auto pdrRecordHandle : pdrRecordHandles)
    {
        changeEntries[0].push_back(pdrRecordHandle);
    }
    if (changeEntries.empty())
    {
        return;
    }
    numsOfChangeEntries[0] = changeEntries[0].size();
    size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
                     PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
                     changeEntries[0].size() * sizeof(uint32_t);
    std::vector<uint8_t> eventDataVec{};
    eventDataVec.resize(maxSize);
    auto eventData =
        reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
            eventDataVec.data());
    size_t actualSize{};
    auto firstEntry = changeEntries[0].data();
    auto rc = encode_pldm_pdr_repository_chg_event_data(
        eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(),
        &firstEntry, eventData, &actualSize, maxSize);
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to encode the repository change event data with response code '{RC}'",
            "RC", static_cast<int>(rc));
        return;
    }
    auto instanceIdResult = instanceIdDb->next(eid);
    if (!instanceIdResult)
    {
        throw pldm::InstanceIdError(instanceIdResult.error());
    }
    auto instanceId = instanceIdResult.value();
    std::vector<uint8_t> requestMsg(
        sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
        actualSize);
    auto request = new (requestMsg.data()) pldm_msg;
    rc = encode_platform_event_message_req(
        instanceId, 1, TERMINUS_ID, PLDM_PDR_REPOSITORY_CHG_EVENT,
        eventDataVec.data(), actualSize, request,
        actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
    if (rc != PLDM_SUCCESS)
    {
        instanceIdDb->free(eid, instanceId);
        error(
            "Failed to encode the platform event message with response code '{RC}'",
            "RC", static_cast<unsigned>(rc));
        return;
    }
    auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
                                                  const pldm_msg* response,
                                                  size_t respMsgLen) {
        if (response == nullptr || !respMsgLen)
        {
            error(
                "Failed to receive response for the PDR repository changed event");
            return;
        }
        uint8_t completionCode{};
        uint8_t status{};
        auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response);
        auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen,
                                                     &completionCode, &status);
        if (rc || completionCode)
        {
            error(
                "Failed to decode platform event message with response code '{RC}' and completion code '{CC}'",
                "RC", static_cast<int>(rc), "CC",
                static_cast<unsigned>(completionCode));
        }
    };
    rc = handler->registerRequest(
        eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
        std::move(requestMsg), std::move(platformEventMessageResponseHandler));
    if (rc)
    {
        error(
            "Failed to send the PDR repository changed event request after CM");
    }
}

Response Handler::getPdrRepositoryInfo(const pldm_msg* request,
                                       size_t payloadLength)
{
    // GetPDRRepositoryInfo request payload should be 0.
    if (payloadLength > 0)
    {
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    Response response(
        sizeof(pldm_msg_hdr) + sizeof(pldm_pdr_repository_info_resp));
    auto responsePtr = new (response.data()) pldm_msg;

    // TODO: Support update times. Currently set to all 0.
    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE];
    memset(updateTime, 0, PLDM_TIMESTAMP104_SIZE);

    uint8_t repository_state =
        pdrCreated ? PLDM_AVAILABLE : PLDM_UPDATE_IN_PROGRESS;

    int rc = encode_get_pdr_repository_info_resp(
        request->hdr.instance_id, PLDM_SUCCESS, repository_state, updateTime,
        updateTime, pdrRepo.getRecordCount(), pdrRepo.getRepositorySize(),
        pdrRepo.getLargestRecordSize(), /*data_transfer_handle_timeout=*/0,
        responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

int Handler::getFilePointer(uint16_t fileIdentifier, FILE** fp,
                            uint32_t* fileSize)
{
    auto it = fileIdentifierToFileInfo.find(fileIdentifier);
    if (it == fileIdentifierToFileInfo.end())
    {
        error(
            "File identifier '{FILE_ID}' not found in fileIdentifierToFileInfo map",
            "FILE_ID", fileIdentifier);
        return -1;
    }

    FILE* original_fp = it->second.fp;
    if (original_fp == nullptr)
    {
        error("Invalid file pointer for file identifier '{FILE_ID}'", "FILE_ID",
              fileIdentifier);
        return -1;
    }

    int original_fd = fileno(original_fp);
    if (original_fd == -1)
    {
        error(
            "Failed to get file descriptor for file pointer for file identifier '{FILE_ID}'",
            "FILE_ID", fileIdentifier);
        return -1;
    }

    int duplicated_fd = dup(original_fd);
    if (duplicated_fd == -1)
    {
        error(
            "Failed to duplicate file descriptor for file identifier '{FILE_ID}'",
            "FILE_ID", fileIdentifier);
        return -1;
    }

    // TODO: the mode should match the original mode. For now read only is
    // supported.
    FILE* duplicated_fp = fdopen(duplicated_fd, "rb");
    if (!duplicated_fp)
    {
        close(duplicated_fd);
        error("Failed to open file descriptor for file identifier '{FILE_ID}'",
              "FILE_ID", fileIdentifier);
        return -1;
    }

    *fp = duplicated_fp;
    *fileSize = it->second.fileSize;

    return 0;
}
} // namespace platform
} // namespace responder
} // namespace pldm
