#pragma once

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

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

#include <phosphor-logging/lg2.hpp>

#include <cmath>
#include <cstdint>
#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
