#pragma once

#include "common/utils.hpp"
#include "libpldmresponder/pdr.hpp"
#include "pdr_utils.hpp"
#include "pldmd/handler.hpp"

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

#include <phosphor-logging/lg2.hpp>

#include <cmath>
#include <cstdint>
#include <map>
#include <optional>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace responder
{
namespace platform_numeric_effecter
{
/** @brief Function to get the effecter value by PDR factor coefficient, etc.
 *  @param[in] pdr - The structure of pldm_numeric_effecter_value_pdr.
 *  @param[in] effecterValue - effecter value.
 *  @param[in] propertyType - type of the D-Bus property.
 *
 *  @return - std::pair<int, std::optional<PropertyValue>> - rc:Success or
 *          failure, PropertyValue: The value to be set
 */
template <typename T>
std::pair<int, std::optional<pldm::utils::PropertyValue>> getEffecterRawValue(
    const pldm_numeric_effecter_value_pdr* pdr, T& effecterValue,
    std::string propertyType)
{
    // X = Round [ (Y - B) / m ]
    // refer to DSP0248_1.2.0 27.8
    int rc = 0;
    pldm::utils::PropertyValue value;
    switch (pdr->effecter_data_size)
    {
        case PLDM_EFFECTER_DATA_SIZE_UINT8:
        {
            auto rawValue = static_cast<uint8_t>(
                round(effecterValue - pdr->offset) / pdr->resolution);
            if (pdr->min_settable.value_u8 < pdr->max_settable.value_u8 &&
                (rawValue < pdr->min_settable.value_u8 ||
                 rawValue > pdr->max_settable.value_u8))
            {
                rc = PLDM_ERROR_INVALID_DATA;
            }
            value = rawValue;
            if (propertyType == "uint64_t")
            {
                auto tempValue = std::get<uint8_t>(value);
                value = static_cast<uint64_t>(tempValue);
            }
            else if (propertyType == "uint32_t")
            {
                auto tempValue = std::get<uint8_t>(value);
                value = static_cast<uint32_t>(tempValue);
            }
            break;
        }
        case PLDM_EFFECTER_DATA_SIZE_SINT8:
        {
            auto rawValue = static_cast<int8_t>(
                round(effecterValue - pdr->offset) / pdr->resolution);
            if (pdr->min_settable.value_s8 < pdr->max_settable.value_s8 &&
                (rawValue < pdr->min_settable.value_s8 ||
                 rawValue > pdr->max_settable.value_s8))
            {
                rc = PLDM_ERROR_INVALID_DATA;
            }
            value = rawValue;
            break;
        }
        case PLDM_EFFECTER_DATA_SIZE_UINT16:
        {
            auto rawValue = static_cast<uint16_t>(
                round(effecterValue - pdr->offset) / pdr->resolution);
            if (pdr->min_settable.value_u16 < pdr->max_settable.value_u16 &&
                (rawValue < pdr->min_settable.value_u16 ||
                 rawValue > pdr->max_settable.value_u16))
            {
                rc = PLDM_ERROR_INVALID_DATA;
            }
            value = rawValue;
            if (propertyType == "uint64_t")
            {
                auto tempValue = std::get<uint16_t>(value);
                value = static_cast<uint64_t>(tempValue);
            }
            else if (propertyType == "uint32_t")
            {
                auto tempValue = std::get<uint16_t>(value);
                value = static_cast<uint32_t>(tempValue);
            }
            break;
        }
        case PLDM_EFFECTER_DATA_SIZE_SINT16:
        {
            auto rawValue = static_cast<int16_t>(
                round(effecterValue - pdr->offset) / pdr->resolution);
            if (pdr->min_settable.value_s16 < pdr->max_settable.value_s16 &&
                (rawValue < pdr->min_settable.value_s16 ||
                 rawValue > pdr->max_settable.value_s16))
            {
                rc = PLDM_ERROR_INVALID_DATA;
            }
            value = rawValue;
            if (propertyType == "uint64_t")
            {
                auto tempValue = std::get<int16_t>(value);
                value = static_cast<uint64_t>(tempValue);
            }
            else if (propertyType == "uint32_t")
            {
                auto tempValue = std::get<int16_t>(value);
                value = static_cast<uint32_t>(tempValue);
            }
            break;
        }
        case PLDM_EFFECTER_DATA_SIZE_UINT32:
        {
            auto rawValue = static_cast<uint32_t>(
                round(effecterValue - pdr->offset) / pdr->resolution);
            if (pdr->min_settable.value_u32 < pdr->max_settable.value_u32 &&
                (rawValue < pdr->min_settable.value_u32 ||
                 rawValue > pdr->max_settable.value_u32))
            {
                rc = PLDM_ERROR_INVALID_DATA;
            }
            value = rawValue;
            if (propertyType == "uint64_t")
            {
                auto tempValue = std::get<uint32_t>(value);
                value = static_cast<uint64_t>(tempValue);
            }
            else if (propertyType == "uint32_t")
            {
                auto tempValue = std::get<uint32_t>(value);
                value = static_cast<uint32_t>(tempValue);
            }
            break;
        }
        case PLDM_EFFECTER_DATA_SIZE_SINT32:
        {
            auto rawValue = static_cast<int32_t>(
                round(effecterValue - pdr->offset) / pdr->resolution);
            if (pdr->min_settable.value_s32 < pdr->max_settable.value_s32 &&
                (rawValue < pdr->min_settable.value_s32 ||
                 rawValue > pdr->max_settable.value_s32))
            {
                rc = PLDM_ERROR_INVALID_DATA;
            }
            value = rawValue;
            if (propertyType == "uint64_t")
            {
                auto tempValue = std::get<int32_t>(value);
                value = static_cast<uint64_t>(tempValue);
            }
            else if (propertyType == "uint32_t")
            {
                auto tempValue = std::get<int32_t>(value);
                value = static_cast<uint32_t>(tempValue);
            }
            break;
        }
    }

    return {rc, std::make_optional(std::move(value))};
}

/** @brief Function to convert the D-Bus value by PDR factor and effecter value.
 *  @param[in] pdr - The structure of pldm_numeric_effecter_value_pdr.
 *  @param[in] effecterDataSize - effecter value size.
 *  @param[in,out] effecterValue - effecter value.
 *  @param[in] propertyType - type of the D-Bus property.
 *
 *  @return std::pair<int, std::optional<PropertyValue>> - rc:Success or
 *          failure, PropertyValue: The value to be set
 */
std::pair<int, std::optional<pldm::utils::PropertyValue>> convertToDbusValue(
    const pldm_numeric_effecter_value_pdr* pdr, uint8_t effecterDataSize,
    uint8_t* effecterValue, std::string propertyType)
{
    if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT8)
    {
        uint8_t currentValue = *(reinterpret_cast<uint8_t*>(&effecterValue[0]));
        return getEffecterRawValue<uint8_t>(pdr, currentValue, propertyType);
    }
    else if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT8)
    {
        int8_t currentValue = *(reinterpret_cast<int8_t*>(&effecterValue[0]));
        return getEffecterRawValue<int8_t>(pdr, currentValue, propertyType);
    }
    else if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16)
    {
        uint16_t currentValue =
            *(reinterpret_cast<uint16_t*>(&effecterValue[0]));
        return getEffecterRawValue<uint16_t>(pdr, currentValue, propertyType);
    }
    else if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
    {
        int16_t currentValue = *(reinterpret_cast<int16_t*>(&effecterValue[0]));
        return getEffecterRawValue<int16_t>(pdr, currentValue, propertyType);
    }
    else if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32)
    {
        uint32_t currentValue =
            *(reinterpret_cast<uint32_t*>(&effecterValue[0]));
        return getEffecterRawValue<uint32_t>(pdr, currentValue, propertyType);
    }
    else if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
    {
        int32_t currentValue = *(reinterpret_cast<int32_t*>(&effecterValue[0]));
        return getEffecterRawValue<int32_t>(pdr, currentValue, propertyType);
    }
    else
    {
        error("Unknown Effecter Size {SIZE}", "SIZE", effecterDataSize);
        return {PLDM_ERROR, {}};
    }
}

/** @brief Function to set the effecter value requested by pldm requester
 *  @tparam[in] DBusInterface - DBus interface type
 *  @tparam[in] Handler - pldm::responder::platform::Handler
 *  @param[in] dBusIntf - The interface object of DBusInterface
 *  @param[in] handler - The interface object of
 *             pldm::responder::platform::Handler
 *  @param[in] effecterId - Effecter ID sent by the requester to act on
 *  @param[in] effecterDataSize - The bit width and format of the setting
 * 				value for the effecter
 *  @param[in] effecter_value - The setting value of numeric effecter being
 * 				requested.
 *  @param[in] effecterValueLength - The setting value length of numeric
 *              effecter being requested.
 *  @return - Success or failure in setting the states. Returns failure in
 * terms of PLDM completion codes if at least one state fails to be set
 */
template <class DBusInterface, class Handler>
int setNumericEffecterValueHandler(
    const DBusInterface& dBusIntf, Handler& handler, uint16_t effecterId,
    uint8_t effecterDataSize, uint8_t* effecterValue,
    size_t effecterValueLength)
{
    constexpr auto effecterValueArrayLength = 4;
    pldm_numeric_effecter_value_pdr* pdr = nullptr;

    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)>
        numericEffecterPdrRepo(pldm_pdr_init(), pldm_pdr_destroy);
    if (!numericEffecterPdrRepo)
    {
        error("Failed to instantiate numeric effecter PDR repository");
        return PLDM_ERROR;
    }
    pldm::responder::pdr_utils::Repo numericEffecterPDRs(
        numericEffecterPdrRepo.get());
    pldm::responder::pdr::getRepoByType(handler.getRepo(), numericEffecterPDRs,
                                        PLDM_NUMERIC_EFFECTER_PDR);
    if (numericEffecterPDRs.empty())
    {
        error("The Numeric Effecter PDR repo is empty.");
        return PLDM_ERROR;
    }

    // Get the pdr structure of pldm_numeric_effecter_value_pdr according
    // to the effecterId
    pldm::responder::pdr_utils::PdrEntry pdrEntry{};
    auto pdrRecord = numericEffecterPDRs.getFirstRecord(pdrEntry);
    while (pdrRecord)
    {
        pdr = new (pdrEntry.data) pldm_numeric_effecter_value_pdr;
        if (pdr->effecter_id != effecterId)
        {
            pdr = nullptr;
            pdrRecord = numericEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
            continue;
        }

        break;
    }

    if (!pdr)
    {
        return PLDM_PLATFORM_INVALID_EFFECTER_ID;
    }

    if (effecterValueLength != effecterValueArrayLength)
    {
        error("Incorrect effecter data size {SIZE}", "SIZE",
              effecterValueLength);
        return PLDM_ERROR_INVALID_DATA;
    }

    try
    {
        const auto& [dbusMappings, dbusValMaps] =
            handler.getDbusObjMaps(effecterId);
        pldm::utils::DBusMapping dbusMapping{
            dbusMappings[0].objectPath, dbusMappings[0].interface,
            dbusMappings[0].propertyName, dbusMappings[0].propertyType};

        // convert to dbus effectervalue according to the factor
        auto [rc, dbusValue] = convertToDbusValue(
            pdr, effecterDataSize, effecterValue, dbusMappings[0].propertyType);
        if (rc != PLDM_SUCCESS)
        {
            return rc;
        }
        try
        {
            dBusIntf.setDbusProperty(dbusMapping, dbusValue.value());
        }
        catch (const std::exception& e)
        {
            error(
                "Failed to set property '{PROPERTY}', interface '{INTERFACE}' and path '{PATH}', error - {ERROR}",
                "PROPERTY", dbusMapping.propertyName, "INTERFACE",
                dbusMapping.interface, "PATH", dbusMapping.objectPath, "ERROR",
                e);
            return PLDM_ERROR;
        }
    }
    catch (const std::out_of_range& e)
    {
        error("Unknown effecter ID '{EFFECTERID}', error - {ERROR}",
              "EFFECTERID", effecterId, "ERROR", e);
        return PLDM_ERROR;
    }

    return PLDM_SUCCESS;
}

/** @brief Function to convert the D-Bus value based on effecter data size
 *         and create the response for getNumericEffecterValue request.
 *  @param[in] PropertyValue - D-Bus Value
 *  @param[in] effecterDataSize - effecter value size.
 *  @param[in,out] responsePtr - Response of getNumericEffecterValue.
 *  @param[in] responsePayloadLength - response length.
 *  @param[in] instanceId - instance id for response
 *
 *  @return PLDM_SUCCESS/PLDM_ERROR
 */
template <typename T>
int getEffecterValue(T propertyValue, uint8_t effecterDataSize,
                     pldm_msg* responsePtr, size_t responsePayloadLength,
                     uint8_t instanceId)
{
    switch (effecterDataSize)
    {
        case PLDM_EFFECTER_DATA_SIZE_UINT8:
        {
            uint8_t value = static_cast<uint8_t>(propertyValue);
            return (encode_get_numeric_effecter_value_resp(
                instanceId, PLDM_SUCCESS, effecterDataSize,
                EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING, &value, &value,
                responsePtr, responsePayloadLength));
        }
        case PLDM_EFFECTER_DATA_SIZE_SINT8:
        {
            int8_t value = static_cast<int8_t>(propertyValue);
            return (encode_get_numeric_effecter_value_resp(
                instanceId, PLDM_SUCCESS, effecterDataSize,
                EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
                reinterpret_cast<uint8_t*>(&value),
                reinterpret_cast<uint8_t*>(&value), responsePtr,
                responsePayloadLength));
        }
        case PLDM_EFFECTER_DATA_SIZE_UINT16:
        {
            uint16_t value = static_cast<uint16_t>(propertyValue);
            return (encode_get_numeric_effecter_value_resp(
                instanceId, PLDM_SUCCESS, effecterDataSize,
                EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
                reinterpret_cast<uint8_t*>(&value),
                reinterpret_cast<uint8_t*>(&value), responsePtr,
                responsePayloadLength));
        }
        case PLDM_EFFECTER_DATA_SIZE_SINT16:
        {
            int16_t value = static_cast<int16_t>(propertyValue);
            return (encode_get_numeric_effecter_value_resp(
                instanceId, PLDM_SUCCESS, effecterDataSize,
                EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
                reinterpret_cast<uint8_t*>(&value),
                reinterpret_cast<uint8_t*>(&value), responsePtr,
                responsePayloadLength));
        }
        case PLDM_EFFECTER_DATA_SIZE_UINT32:
        {
            uint32_t value = static_cast<uint32_t>(propertyValue);
            return (encode_get_numeric_effecter_value_resp(
                instanceId, PLDM_SUCCESS, effecterDataSize,
                EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
                reinterpret_cast<uint8_t*>(&value),
                reinterpret_cast<uint8_t*>(&value), responsePtr,
                responsePayloadLength));
        }
        case PLDM_EFFECTER_DATA_SIZE_SINT32:
        {
            int32_t value = static_cast<int32_t>(propertyValue);
            return (encode_get_numeric_effecter_value_resp(
                instanceId, PLDM_SUCCESS, effecterDataSize,
                EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
                reinterpret_cast<uint8_t*>(&value),
                reinterpret_cast<uint8_t*>(&value), responsePtr,
                responsePayloadLength));
        }
        default:
        {
            error("Unknown Effecter Size {SIZE}", "SIZE", effecterDataSize);
            return PLDM_ERROR;
        }
    }
}

/** @brief Function to convert the D-Bus value to the effector data size value
 *  @param[in] PropertyType - String contains the dataType of the Dbus value.
 *  @param[in] PropertyValue - Variant contains the D-Bus Value
 *  @param[in] effecterDataSize - effecter value size.
 *  @param[in,out] responsePtr - Response of getNumericEffecterValue.
 *  @param[in] responsePayloadLength - response length.
 *  @param[in] instanceId - instance id for response
 *
 *  @return PLDM_SUCCESS/PLDM_ERROR
 */
int getNumericEffecterValueHandler(
    const std::string& propertyType, pldm::utils::PropertyValue propertyValue,
    uint8_t effecterDataSize, pldm_msg* responsePtr,
    size_t responsePayloadLength, uint8_t instanceId)
{
    if (propertyType == "uint8_t")
    {
        uint8_t propVal = std::get<uint8_t>(propertyValue);
        return getEffecterValue<uint8_t>(propVal, effecterDataSize, responsePtr,
                                         responsePayloadLength, instanceId);
    }
    else if (propertyType == "uint16_t")
    {
        uint16_t propVal = std::get<uint16_t>(propertyValue);
        return getEffecterValue<uint16_t>(propVal, effecterDataSize,
                                          responsePtr, responsePayloadLength,
                                          instanceId);
    }
    else if (propertyType == "uint32_t")
    {
        uint32_t propVal = std::get<uint32_t>(propertyValue);
        return getEffecterValue<uint32_t>(propVal, effecterDataSize,
                                          responsePtr, responsePayloadLength,
                                          instanceId);
    }
    else if (propertyType == "uint64_t")
    {
        uint64_t propVal = std::get<uint64_t>(propertyValue);
        return getEffecterValue<uint64_t>(propVal, effecterDataSize,
                                          responsePtr, responsePayloadLength,
                                          instanceId);
    }
    else
    {
        error("Property type '{TYPE}' not supported", "TYPE", propertyType);
    }
    return PLDM_ERROR;
}

/** @brief Function to get the effecter details as data size, D-Bus property
 *         type, D-Bus Value
 *  @tparam[in] DBusInterface - DBus interface type
 *  @tparam[in] Handler - pldm::responder::platform::Handler
 *  @param[in] dBusIntf - The interface object of DBusInterface
 *  @param[in] handler - The interface object of
 *             pldm::responder::platform::Handler
 *  @param[in] effecterId - Effecter ID sent by the requester to act on
 *  @param[in] effecterDataSize - The bit width and format of the setting
 *             value for the effecter
 *  @param[in] propertyType - The data type of the D-Bus value
 *  @param[in] propertyValue - The value of numeric effecter being
 *                             requested.
 *  @return - Success or failure in getting the D-Bus property or the
 *  effecterId not found in the PDR repo
 */
template <class DBusInterface, class Handler>
int getNumericEffecterData(const DBusInterface& dBusIntf, Handler& handler,
                           uint16_t effecterId, uint8_t& effecterDataSize,
                           std::string& propertyType,
                           pldm::utils::PropertyValue& propertyValue)
{
    pldm_numeric_effecter_value_pdr* pdr = nullptr;

    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)>
        numericEffecterPdrRepo(pldm_pdr_init(), pldm_pdr_destroy);
    pldm::responder::pdr_utils::Repo numericEffecterPDRs(
        numericEffecterPdrRepo.get());
    pldm::responder::pdr::getRepoByType(handler.getRepo(), numericEffecterPDRs,
                                        PLDM_NUMERIC_EFFECTER_PDR);
    if (numericEffecterPDRs.empty())
    {
        error("The Numeric Effecter PDR repo is empty.");
        return PLDM_ERROR;
    }

    // Get the pdr structure of pldm_numeric_effecter_value_pdr according
    // to the effecterId
    pldm::responder::pdr_utils::PdrEntry pdrEntry{};
    auto pdrRecord = numericEffecterPDRs.getFirstRecord(pdrEntry);

    while (pdrRecord)
    {
        pdr = new (pdrEntry.data) pldm_numeric_effecter_value_pdr;
        if (pdr->effecter_id != effecterId)
        {
            pdr = nullptr;
            pdrRecord = numericEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
            continue;
        }
        effecterDataSize = pdr->effecter_data_size;
        break;
    }

    if (!pdr)
    {
        error("Failed to find numeric effecter ID {EFFECTERID}", "EFFECTERID",
              effecterId);
        return PLDM_PLATFORM_INVALID_EFFECTER_ID;
    }

    pldm::utils::DBusMapping dbusMapping{};
    try
    {
        const auto& [dbusMappings, dbusValMaps] =
            handler.getDbusObjMaps(effecterId);
        if (dbusMappings.size() > 0)
        {
            dbusMapping = {
                dbusMappings[0].objectPath, dbusMappings[0].interface,
                dbusMappings[0].propertyName, dbusMappings[0].propertyType};

            propertyValue = dBusIntf.getDbusPropertyVariant(
                dbusMapping.objectPath.c_str(),
                dbusMapping.propertyName.c_str(),
                dbusMapping.interface.c_str());
            propertyType = dbusMappings[0].propertyType;
        }
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to do dbus mapping or the dbus query for the effecter ID '{EFFECTERID}', error - {ERROR}",
            "EFFECTERID", effecterId, "ERROR", e);
        error(
            "Dbus Details path [{PATH}], interface [{INTERFACE}] and  property [{PROPERTY}]",
            "PATH", dbusMapping.objectPath, "INTERFACE", dbusMapping.interface,
            "PROPERTY", dbusMapping.propertyName);
        return PLDM_ERROR;
    }

    return PLDM_SUCCESS;
}

} // namespace platform_numeric_effecter
} // namespace responder
} // namespace pldm
