#include "pldm.hpp"

#include "file.hpp"

#include <fmt/core.h>
#include <libpldm/entity.h>
#include <libpldm/platform.h>
#include <libpldm/state_set.h>

#include <phosphor-logging/log.hpp>

namespace pldm
{

using sdbusplus::exception::SdBusError;
using namespace phosphor::logging;

void Interface::fetchOCCSensorInfo(const PdrList& pdrs,
                                   SensorToOCCInstance& sensorInstanceMap,
                                   SensorOffset& sensorOffset)
{
    bool offsetFound = false;
    auto pdr =
        reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
    auto possibleStatesPtr = pdr->possible_states;
    for (auto offset = 0; offset < pdr->composite_sensor_count; offset++)
    {
        auto possibleStates =
            reinterpret_cast<const state_sensor_possible_states*>(
                possibleStatesPtr);

        if (possibleStates->state_set_id ==
            PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS)
        {
            sensorOffset = offset;
            offsetFound = true;
            break;
        }
        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
                             sizeof(possibleStates->possible_states_size) +
                             possibleStates->possible_states_size;
    }

    if (!offsetFound)
    {
        log<level::ERR>("pldm: OCC state sensor PDR with StateSetId "
                        "PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS not found");
        return;
    }

    // To order SensorID based on the EntityInstance
    std::map<EntityInstance, SensorID> entityInstMap{};
    for (auto& pdr : pdrs)
    {
        auto pdrPtr =
            reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
        entityInstMap.emplace(
            static_cast<EntityInstance>(pdrPtr->entity_instance),
            static_cast<SensorID>(pdrPtr->sensor_id));
    }

    open_power::occ::instanceID count = start;
    for (auto const& pair : entityInstMap)
    {
        sensorInstanceMap.emplace(pair.second, count);
        count++;
    }
}

void Interface::sensorEvent(sdbusplus::message::message& msg)
{
    if (!isOCCSensorCacheValid())
    {
        PdrList pdrs{};

        auto& bus = open_power::occ::utils::getBus();
        try
        {
            auto method = bus.new_method_call(
                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
                "xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
            method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
                          (uint16_t)PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS);

            auto responseMsg = bus.call(method);
            responseMsg.read(pdrs);
        }
        catch (const SdBusError& e)
        {
            log<level::ERR>("pldm: Failed to fetch the OCC state sensor PDRs",
                            entry("ERROR=%s", e.what()));
        }

        if (!pdrs.size())
        {
            log<level::ERR>("pldm: OCC state sensor PDRs not present");
            return;
        }

        fetchOCCSensorInfo(pdrs, sensorToOCCInstance, sensorOffset);
    }

    TerminusID tid{};
    SensorID sensorId{};
    SensorOffset msgSensorOffset{};
    EventState eventState{};
    EventState previousEventState{};

    msg.read(tid, sensorId, msgSensorOffset, eventState, previousEventState);

    auto sensorEntry = sensorToOCCInstance.find(sensorId);
    if (sensorEntry == sensorToOCCInstance.end() ||
        (msgSensorOffset != sensorOffset))
    {
        // No action for non matching sensorEvents
        return;
    }

    if (eventState == static_cast<EventState>(
                          PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
    {
        log<level::INFO>(
            fmt::format("PLDM: OCC{} is RUNNING", sensorEntry->second).c_str());
        callBack(sensorEntry->second, true);
    }
    else if (eventState ==
             static_cast<EventState>(
                 PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
    {
        log<level::INFO>(
            fmt::format("PLDM: OCC{} has now STOPPED", sensorEntry->second)
                .c_str());
        callBack(sensorEntry->second, false);
    }

    return;
}

void Interface::hostStateEvent(sdbusplus::message::message& msg)
{
    std::map<std::string, std::variant<std::string>> properties{};
    std::string interface;
    msg.read(interface, properties);
    const auto stateEntry = properties.find("CurrentHostState");
    if (stateEntry != properties.end())
    {
        auto stateEntryValue = stateEntry->second;
        auto propVal = std::get<std::string>(stateEntryValue);
        if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
        {
            sensorToOCCInstance.clear();
            occInstanceToEffecter.clear();
        }
    }
}

void Interface::fetchOCCEffecterInfo(
    const PdrList& pdrs, OccInstanceToEffecter& instanceToEffecterMap,
    CompositeEffecterCount& count, uint8_t& bootRestartPos)
{
    bool offsetFound = false;
    auto pdr =
        reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
    auto possibleStatesPtr = pdr->possible_states;
    for (auto offset = 0; offset < pdr->composite_effecter_count; offset++)
    {
        auto possibleStates =
            reinterpret_cast<const state_effecter_possible_states*>(
                possibleStatesPtr);

        if (possibleStates->state_set_id == PLDM_STATE_SET_BOOT_RESTART_CAUSE)
        {
            bootRestartPos = offset;
            effecterCount = pdr->composite_effecter_count;
            offsetFound = true;
            break;
        }
        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
                             sizeof(possibleStates->possible_states_size) +
                             possibleStates->possible_states_size;
    }

    if (!offsetFound)
    {
        return;
    }

    std::map<EntityInstance, EffecterID> entityInstMap{};
    for (auto& pdr : pdrs)
    {
        auto pdrPtr =
            reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
        entityInstMap.emplace(
            static_cast<EntityInstance>(pdrPtr->entity_instance),
            static_cast<SensorID>(pdrPtr->effecter_id));
    }

    open_power::occ::instanceID position = start;
    for (auto const& pair : entityInstMap)
    {
        occInstanceToEffecter.emplace(position, pair.second);
        position++;
    }
}

std::vector<uint8_t>
    Interface::prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
                                     CompositeEffecterCount effecterCount,
                                     uint8_t bootRestartPos)
{
    std::vector<uint8_t> request(
        sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
        (effecterCount * sizeof(set_effecter_state_field)));
    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
    std::vector<set_effecter_state_field> stateField;

    for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
    {
        if (effecterPos == bootRestartPos)
        {
            stateField.emplace_back(set_effecter_state_field{
                PLDM_REQUEST_SET,
                PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET});
        }
        else
        {
            stateField.emplace_back(
                set_effecter_state_field{PLDM_NO_CHANGE, 0});
        }
    }
    auto rc = encode_set_state_effecter_states_req(
        instanceId, effecterId, effecterCount, stateField.data(), requestMsg);
    if (rc != PLDM_SUCCESS)
    {
        log<level::ERR>("encode set effecter states request returned error ",
                        entry("RC=%d", rc));
        request.clear();
    }
    return request;
}

void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
{
    if (!isPDREffecterCacheValid())
    {
        PdrList pdrs{};

        auto& bus = open_power::occ::utils::getBus();
        try
        {
            auto method = bus.new_method_call(
                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
                "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
            method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
                          (uint16_t)PLDM_STATE_SET_BOOT_RESTART_CAUSE);

            auto responseMsg = bus.call(method);
            responseMsg.read(pdrs);
        }
        catch (const SdBusError& e)
        {
            log<level::ERR>("pldm: Failed to fetch the OCC state effecter PDRs",
                            entry("ERROR=%s", e.what()));
        }

        if (!pdrs.size())
        {
            log<level::ERR>("pldm: OCC state effecter PDRs not present");
            return;
        }

        fetchOCCEffecterInfo(pdrs, occInstanceToEffecter, effecterCount,
                             bootRestartPosition);
    }

    // Find the matching effecter for the OCC instance
    auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
    if (effecterEntry == occInstanceToEffecter.end())
    {
        log<level::ERR>(
            "pldm: Failed to find a matching effecter for OCC instance",
            entry("OCC_INSTANCE_ID=%d", occInstanceId));

        return;
    }

    uint8_t instanceId{};

    auto& bus = open_power::occ::utils::getBus();
    try
    {
        auto method = bus.new_method_call(
            "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
            "xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
        method.append(mctpEid);
        auto reply = bus.call(method);
        reply.read(instanceId);
    }
    catch (const SdBusError& e)
    {
        log<level::ERR>("pldm: GetInstanceId returned error",
                        entry("ERROR=%s", e.what()));
        return;
    }

    // Prepare the SetStateEffecterStates request to reset the OCC
    auto request = prepareSetEffecterReq(instanceId, effecterEntry->second,
                                         effecterCount, bootRestartPosition);

    if (request.empty())
    {
        log<level::ERR>("pldm: SetStateEffecterStates request message empty");
        return;
    }

    // Connect to MCTP scoket
    int fd = pldm_open();
    if (fd == -1)
    {
        log<level::ERR>("pldm: Failed to connect to MCTP socket");
        return;
    }
    open_power::occ::FileDescriptor fileFd(fd);

    // Send the PLDM request message to HBRT
    uint8_t* response = nullptr;
    size_t responseSize{};
    auto rc = pldm_send_recv(mctpEid, fileFd(), request.data(), request.size(),
                             &response, &responseSize);
    std::unique_ptr<uint8_t, decltype(std::free)*> responsePtr{response,
                                                               std::free};
    if (rc)
    {
        log<level::ERR>("pldm: pldm_send_recv failed for OCC reset",
                        entry("RC=%d", rc));
    }

    uint8_t completionCode{};
    auto responseMsg = reinterpret_cast<const pldm_msg*>(responsePtr.get());
    auto rcDecode = decode_set_state_effecter_states_resp(
        responseMsg, responseSize - sizeof(pldm_msg_hdr), &completionCode);
    if (rcDecode || completionCode)
    {
        log<level::ERR>(
            "pldm: decode_set_state_effecter_states_resp returned error",
            entry("RC=%d", rcDecode),
            entry("COMPLETION_CODE=%d", completionCode));
    }

    return;
}

} // namespace pldm
