#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.
    // Note that when a proc is on a DCM, the PDRs for these sensors
    // could have the same instance IDs but different container IDs.
    std::map<uint32_t, SensorID> entityInstMap{};
    for (auto& pdr : pdrs)
    {
        auto pdrPtr =
            reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
        uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
                       static_cast<uint32_t>(pdrPtr->entity_instance);
        entityInstMap.emplace(key, 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,
                          (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());
        uint32_t key = (static_cast<uint32_t>(pdrPtr->container_id) << 16) |
                       static_cast<uint32_t>(pdrPtr->entity_instance);
        entityInstMap.emplace(key, 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
