#include "utils.hpp"

#include <libpldm/pdr.h>
#include <libpldm/pldm_types.h>
#include <linux/mctp.h>

#include <xyz/openbmc_project/BIOSConfig/Manager/client.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Inventory/Item/common.hpp>
#include <xyz/openbmc_project/Logging/Create/client.hpp>
#include <xyz/openbmc_project/ObjectMapper/client.hpp>
#include <xyz/openbmc_project/PLDM/Event/common.hpp>

#include <algorithm>
#include <cctype>
#include <ctime>
#include <fstream>
#include <iostream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace utils
{

using ObjectMapper = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>;
using BIOSConfigManager =
    sdbusplus::client::xyz::openbmc_project::bios_config::Manager<>;
using PLDMEvent = sdbusplus::common::xyz::openbmc_project::pldm::Event;
using InventoryItem = sdbusplus::common::xyz::openbmc_project::inventory::Item;

constexpr const char* MCTP_INTERFACE_CC = "au.com.codeconstruct.MCTP.Endpoint1";
constexpr const char* MCTP_ENDPOINT_RECOVER_METHOD = "Recover";

std::vector<std::vector<uint8_t>> findStateEffecterPDR(
    uint8_t /*tid*/, uint16_t entityID, uint16_t stateSetId,
    const pldm_pdr* repo)
{
    uint8_t* outData = nullptr;
    uint32_t size{};
    const pldm_pdr_record* record{};
    std::vector<std::vector<uint8_t>> pdrs;
    try
    {
        do
        {
            record = pldm_pdr_find_record_by_type(repo, PLDM_STATE_EFFECTER_PDR,
                                                  record, &outData, &size);
            if (record)
            {
                auto pdr = new (outData) pldm_state_effecter_pdr;
                auto compositeEffecterCount = pdr->composite_effecter_count;
                auto possible_states_start = pdr->possible_states;

                for (auto effecters = 0x00; effecters < compositeEffecterCount;
                     effecters++)
                {
                    auto possibleStates = new (possible_states_start)
                        state_effecter_possible_states;
                    auto setId = possibleStates->state_set_id;
                    auto possibleStateSize =
                        possibleStates->possible_states_size;

                    if (pdr->entity_type == entityID && setId == stateSetId)
                    {
                        std::vector<uint8_t> effecter_pdr(&outData[0],
                                                          &outData[size]);
                        pdrs.emplace_back(std::move(effecter_pdr));
                        break;
                    }
                    possible_states_start += possibleStateSize + sizeof(setId) +
                                             sizeof(possibleStateSize);
                }
            }

        } while (record);
    }
    catch (const std::exception& e)
    {
        error("Failed to obtain a record, error - {ERROR}", "ERROR", e);
    }

    return pdrs;
}

std::vector<std::vector<uint8_t>> findStateSensorPDR(
    uint8_t /*tid*/, uint16_t entityID, uint16_t stateSetId,
    const pldm_pdr* repo)
{
    uint8_t* outData = nullptr;
    uint32_t size{};
    const pldm_pdr_record* record{};
    std::vector<std::vector<uint8_t>> pdrs;
    try
    {
        do
        {
            record = pldm_pdr_find_record_by_type(repo, PLDM_STATE_SENSOR_PDR,
                                                  record, &outData, &size);
            if (record)
            {
                auto pdr = new (outData) pldm_state_sensor_pdr;
                auto compositeSensorCount = pdr->composite_sensor_count;
                auto possible_states_start = pdr->possible_states;

                for (auto sensors = 0x00; sensors < compositeSensorCount;
                     sensors++)
                {
                    auto possibleStates = new (possible_states_start)
                        state_sensor_possible_states;
                    auto setId = possibleStates->state_set_id;
                    auto possibleStateSize =
                        possibleStates->possible_states_size;

                    if (pdr->entity_type == entityID && setId == stateSetId)
                    {
                        std::vector<uint8_t> sensor_pdr(&outData[0],
                                                        &outData[size]);
                        pdrs.emplace_back(std::move(sensor_pdr));
                        break;
                    }
                    possible_states_start += possibleStateSize + sizeof(setId) +
                                             sizeof(possibleStateSize);
                }
            }

        } while (record);
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to obtain a record with entity ID '{ENTITYID}', error - {ERROR}",
            "ENTITYID", entityID, "ERROR", e);
    }

    return pdrs;
}

uint8_t readHostEID()
{
    uint8_t eid{};
    std::ifstream eidFile{HOST_EID_PATH};
    if (!eidFile.good())
    {
        error("Failed to open remote terminus EID file at path '{PATH}'",
              "PATH", static_cast<std::string>(HOST_EID_PATH));
    }
    else
    {
        std::string eidStr;
        eidFile >> eidStr;
        if (!eidStr.empty())
        {
            eid = atoi(eidStr.c_str());
        }
        else
        {
            error("Remote terminus EID file was empty");
        }
    }

    return eid;
}

bool isValidEID(eid mctpEid)
{
    if (mctpEid == MCTP_ADDR_NULL || mctpEid < MCTP_START_VALID_EID ||
        mctpEid == MCTP_ADDR_ANY)
    {
        return false;
    }

    return true;
}

uint8_t getNumPadBytes(uint32_t data)
{
    uint8_t pad = 0;
    pad = ((data % 4) ? (4 - data % 4) : 0);
    return pad;
} // end getNumPadBytes

bool uintToDate(uint64_t data, uint16_t* year, uint8_t* month, uint8_t* day,
                uint8_t* hour, uint8_t* min, uint8_t* sec)
{
    constexpr uint64_t max_data = 29991231115959;
    constexpr uint64_t min_data = 19700101000000;
    if (data < min_data || data > max_data)
    {
        return false;
    }

    *year = data / 10000000000;
    data = data % 10000000000;
    *month = data / 100000000;
    data = data % 100000000;
    *day = data / 1000000;
    data = data % 1000000;
    *hour = data / 10000;
    data = data % 10000;
    *min = data / 100;
    *sec = data % 100;

    return true;
}

std::optional<std::vector<set_effecter_state_field>> parseEffecterData(
    const std::vector<uint8_t>& effecterData, uint8_t effecterCount)
{
    std::vector<set_effecter_state_field> stateField;

    if (effecterData.size() != effecterCount * 2)
    {
        return std::nullopt;
    }

    for (uint8_t i = 0; i < effecterCount; ++i)
    {
        uint8_t set_request = effecterData[i * 2] == PLDM_REQUEST_SET
                                  ? PLDM_REQUEST_SET
                                  : PLDM_NO_CHANGE;
        set_effecter_state_field filed{set_request, effecterData[i * 2 + 1]};
        stateField.emplace_back(std::move(filed));
    }

    return std::make_optional(std::move(stateField));
}

std::string DBusHandler::getService(const char* path,
                                    const char* interface) const
{
    using DbusInterfaceList = std::vector<std::string>;
    std::map<std::string, std::vector<std::string>> mapperResponse;
    auto& bus = DBusHandler::getBus();

    auto mapper = bus.new_method_call(
        ObjectMapper::default_service, ObjectMapper::instance_path,
        ObjectMapper::interface, ObjectMapper::method_names::get_object);

    if (interface)
    {
        mapper.append(path, DbusInterfaceList({interface}));
    }
    else
    {
        mapper.append(path, DbusInterfaceList({}));
    }

    auto mapperResponseMsg = bus.call(mapper, dbusTimeout);
    mapperResponseMsg.read(mapperResponse);
    return mapperResponse.begin()->first;
}

GetSubTreeResponse DBusHandler::getSubtree(
    const std::string& searchPath, int depth,
    const std::vector<std::string>& ifaceList) const
{
    auto& bus = pldm::utils::DBusHandler::getBus();
    auto method = bus.new_method_call(
        ObjectMapper::default_service, ObjectMapper::instance_path,
        ObjectMapper::interface, ObjectMapper::method_names::get_sub_tree);
    method.append(searchPath, depth, ifaceList);
    auto reply = bus.call(method, dbusTimeout);
    auto response = reply.unpack<GetSubTreeResponse>();

    return response;
}

GetSubTreePathsResponse DBusHandler::getSubTreePaths(
    const std::string& objectPath, int depth,
    const std::vector<std::string>& ifaceList) const
{
    std::vector<std::string> paths;
    auto& bus = pldm::utils::DBusHandler::getBus();
    auto method = bus.new_method_call(
        ObjectMapper::default_service, ObjectMapper::instance_path,
        ObjectMapper::interface,
        ObjectMapper::method_names::get_sub_tree_paths);
    method.append(objectPath, depth, ifaceList);
    auto reply = bus.call(method, dbusTimeout);

    reply.read(paths);
    return paths;
}

GetAncestorsResponse DBusHandler::getAncestors(
    const std::string& path, const std::vector<std::string>& ifaceList) const
{
    auto& bus = pldm::utils::DBusHandler::getBus();
    auto method = bus.new_method_call(
        ObjectMapper::default_service, ObjectMapper::instance_path,
        ObjectMapper::interface, ObjectMapper::method_names::get_ancestors);
    method.append(path, ifaceList);
    auto reply = bus.call(method, dbusTimeout);
    auto response = reply.unpack<GetAncestorsResponse>();

    return response;
}

void reportError(const char* errorMsg)
{
    auto& bus = pldm::utils::DBusHandler::getBus();
    using LoggingCreate =
        sdbusplus::client::xyz::openbmc_project::logging::Create<>;
    try
    {
        using namespace sdbusplus::xyz::openbmc_project::Logging::server;
        auto severity =
            sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
                sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
                    Error);
        auto method = bus.new_method_call(
            LoggingCreate::default_service, LoggingCreate::instance_path,
            LoggingCreate::interface, LoggingCreate::method_names::create);

        std::map<std::string, std::string> addlData{};
        method.append(errorMsg, severity, addlData);
        bus.call_noreply(method, dbusTimeout);
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to do dbus call for creating error log for '{ERRMSG}' at path '{PATH}' and interface '{INTERFACE}', error - {ERROR}",
            "ERRMSG", errorMsg, "PATH", LoggingCreate::instance_path,
            "INTERFACE", LoggingCreate::interface, "ERROR", e);
    }
}

void DBusHandler::setDbusProperty(const DBusMapping& dBusMap,
                                  const PropertyValue& value) const
{
    auto setDbusValue = [&dBusMap, this](const auto& variant) {
        auto& bus = getBus();
        auto service =
            getService(dBusMap.objectPath.c_str(), dBusMap.interface.c_str());
        auto method = bus.new_method_call(
            service.c_str(), dBusMap.objectPath.c_str(), dbusProperties, "Set");
        method.append(dBusMap.interface.c_str(), dBusMap.propertyName.c_str(),
                      variant);
        bus.call_noreply(method, dbusTimeout);
    };

    if (dBusMap.propertyType == "uint8_t")
    {
        std::variant<uint8_t> v = std::get<uint8_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "bool")
    {
        std::variant<bool> v = std::get<bool>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "int16_t")
    {
        std::variant<int16_t> v = std::get<int16_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "uint16_t")
    {
        std::variant<uint16_t> v = std::get<uint16_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "int32_t")
    {
        std::variant<int32_t> v = std::get<int32_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "uint32_t")
    {
        std::variant<uint32_t> v = std::get<uint32_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "int64_t")
    {
        std::variant<int64_t> v = std::get<int64_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "uint64_t")
    {
        std::variant<uint64_t> v = std::get<uint64_t>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "double")
    {
        std::variant<double> v = std::get<double>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "string")
    {
        std::variant<std::string> v = std::get<std::string>(value);
        setDbusValue(v);
    }
    else if (dBusMap.propertyType == "array[string]")
    {
        std::variant<std::vector<std::string>> v =
            std::get<std::vector<std::string>>(value);
        setDbusValue(v);
    }
    else
    {
        error("Unsupported property type '{TYPE}'", "TYPE",
              dBusMap.propertyType);
        throw std::invalid_argument("UnSupported Dbus Type");
    }
}

PropertyValue DBusHandler::getDbusPropertyVariant(
    const char* objPath, const char* dbusProp, const char* dbusInterface) const
{
    auto& bus = DBusHandler::getBus();
    auto service = getService(objPath, dbusInterface);
    auto method =
        bus.new_method_call(service.c_str(), objPath, dbusProperties, "Get");
    method.append(dbusInterface, dbusProp);
    return bus.call(method, dbusTimeout).unpack<PropertyValue>();
}

GetAssociatedSubTreeResponse DBusHandler::getAssociatedSubTree(
    const sdbusplus::object_path& objectPath,
    const sdbusplus::object_path& subtree, int depth,
    const std::vector<std::string>& ifaceList) const
{
    auto& bus = DBusHandler::getBus();
    auto method = bus.new_method_call(
        ObjectMapper::default_service, ObjectMapper::instance_path,
        ObjectMapper::interface,
        ObjectMapper::method_names::get_associated_sub_tree);
    method.append(objectPath, subtree, depth, ifaceList);
    auto reply = bus.call(method, dbusTimeout);
    auto response = reply.unpack<GetAssociatedSubTreeResponse>();

    return response;
}

ObjectValueTree DBusHandler::getManagedObj(const char* service,
                                           const char* rootPath)
{
    auto& bus = DBusHandler::getBus();
    auto method = bus.new_method_call(service, rootPath,
                                      "org.freedesktop.DBus.ObjectManager",
                                      "GetManagedObjects");
    return bus.call(method).unpack<ObjectValueTree>();
}

PropertyMap DBusHandler::getDbusPropertiesVariant(
    const char* serviceName, const char* objPath,
    const char* dbusInterface) const
{
    auto& bus = DBusHandler::getBus();
    auto method =
        bus.new_method_call(serviceName, objPath, dbusProperties, "GetAll");
    method.append(dbusInterface);
    return bus.call(method, dbusTimeout).unpack<PropertyMap>();
}

PropertyValue jsonEntryToDbusVal(std::string_view type,
                                 const nlohmann::json& value)
{
    PropertyValue propValue{};
    if (type == "uint8_t")
    {
        propValue = static_cast<uint8_t>(value);
    }
    else if (type == "uint16_t")
    {
        propValue = static_cast<uint16_t>(value);
    }
    else if (type == "uint32_t")
    {
        propValue = static_cast<uint32_t>(value);
    }
    else if (type == "uint64_t")
    {
        propValue = static_cast<uint64_t>(value);
    }
    else if (type == "int16_t")
    {
        propValue = static_cast<int16_t>(value);
    }
    else if (type == "int32_t")
    {
        propValue = static_cast<int32_t>(value);
    }
    else if (type == "int64_t")
    {
        propValue = static_cast<int64_t>(value);
    }
    else if (type == "bool")
    {
        propValue = static_cast<bool>(value);
    }
    else if (type == "double")
    {
        propValue = static_cast<double>(value);
    }
    else if (type == "string")
    {
        propValue = static_cast<std::string>(value);
    }
    else
    {
        error("Unknown D-Bus property type '{TYPE}'", "TYPE", type);
    }

    return propValue;
}

uint16_t findStateEffecterId(const pldm_pdr* pdrRepo, uint16_t entityType,
                             uint16_t entityInstance, uint16_t containerId,
                             uint16_t stateSetId, bool localOrRemote)
{
    uint8_t* pdrData = nullptr;
    uint32_t pdrSize{};
    const pldm_pdr_record* record{};
    do
    {
        record = pldm_pdr_find_record_by_type(pdrRepo, PLDM_STATE_EFFECTER_PDR,
                                              record, &pdrData, &pdrSize);
        if (record && (localOrRemote ^ pldm_pdr_record_is_remote(record)))
        {
            auto pdr = new (pdrData) pldm_state_effecter_pdr;
            auto compositeEffecterCount = pdr->composite_effecter_count;
            auto possible_states_start = pdr->possible_states;

            for (auto effecters = 0x00; effecters < compositeEffecterCount;
                 effecters++)
            {
                auto possibleStates = new (possible_states_start)
                    state_effecter_possible_states;
                auto setId = possibleStates->state_set_id;
                auto possibleStateSize = possibleStates->possible_states_size;

                if (entityType == pdr->entity_type &&
                    entityInstance == pdr->entity_instance &&
                    containerId == pdr->container_id && stateSetId == setId)
                {
                    return pdr->effecter_id;
                }
                possible_states_start += possibleStateSize + sizeof(setId) +
                                         sizeof(possibleStateSize);
            }
        }
    } while (record);

    return PLDM_INVALID_EFFECTER_ID;
}

int emitStateSensorEventSignal(uint8_t tid, uint16_t sensorId,
                               uint8_t sensorOffset, uint8_t eventState,
                               uint8_t previousEventState)
{
    try
    {
        auto& bus = DBusHandler::getBus();
        auto msg =
            bus.new_signal("/xyz/openbmc_project/pldm", PLDMEvent::interface,
                           PLDMEvent::signal_names::state_sensor_event);
        msg.append(tid, sensorId, sensorOffset, eventState, previousEventState);

        msg.signal_send();
    }
    catch (const std::exception& e)
    {
        error("Failed to emit pldm event signal, error - {ERROR}", "ERROR", e);
        return PLDM_ERROR;
    }

    return PLDM_SUCCESS;
}

void recoverMctpEndpoint(const std::string& endpointObjPath)
{
    auto& bus = DBusHandler::getBus();
    try
    {
        std::string service = DBusHandler().getService(endpointObjPath.c_str(),
                                                       MCTP_INTERFACE_CC);

        auto method = bus.new_method_call(
            service.c_str(), endpointObjPath.c_str(), MCTP_INTERFACE_CC,
            MCTP_ENDPOINT_RECOVER_METHOD);
        bus.call_noreply(method, dbusTimeout);
    }
    catch (const std::exception& e)
    {
        error(
            "failed to make a D-Bus call to recover MCTP Endpoint, ERROR {ERR_EXCEP}",
            "ERR_EXCEP", e);
    }
}

uint16_t findStateSensorId(const pldm_pdr* pdrRepo, uint8_t tid,
                           uint16_t entityType, uint16_t entityInstance,
                           uint16_t containerId, uint16_t stateSetId)
{
    auto pdrs = findStateSensorPDR(tid, entityType, stateSetId, pdrRepo);
    for (auto pdr : pdrs)
    {
        auto sensorPdr = new (pdr.data()) pldm_state_sensor_pdr;
        auto compositeSensorCount = sensorPdr->composite_sensor_count;
        auto possible_states_start = sensorPdr->possible_states;

        for (auto sensors = 0x00; sensors < compositeSensorCount; sensors++)
        {
            auto possibleStates = new (possible_states_start)
                state_sensor_possible_states;
            auto setId = possibleStates->state_set_id;
            auto possibleStateSize = possibleStates->possible_states_size;
            if (entityType == sensorPdr->entity_type &&
                entityInstance == sensorPdr->entity_instance &&
                stateSetId == setId && containerId == sensorPdr->container_id)
            {
                return sensorPdr->sensor_id;
            }
            possible_states_start +=
                possibleStateSize + sizeof(setId) + sizeof(possibleStateSize);
        }
    }
    return PLDM_INVALID_EFFECTER_ID;
}

void printBuffer(bool isTx, const std::vector<uint8_t>& buffer)
{
    if (buffer.empty())
    {
        return;
    }

    std::cout << (isTx ? "Tx: " : "Rx: ");

    std::ranges::for_each(buffer, [](uint8_t byte) {
        std::cout << std::format("{:02x} ", byte);
    });

    std::cout << std::endl;
}

std::string toString(const struct variable_field& var)
{
    if (var.ptr == nullptr || !var.length)
    {
        return "";
    }

    std::string str(reinterpret_cast<const char*>(var.ptr), var.length);
    std::replace_if(
        str.begin(), str.end(), [](const char& c) { return !isprint(c); }, ' ');
    return str;
}

std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
                               std::string_view trimStr)
{
    std::vector<std::string> out;
    size_t start = 0;
    size_t end = 0;

    while ((start = srcStr.find_first_not_of(delim, end)) != std::string::npos)
    {
        end = srcStr.find(delim, start);
        std::string_view dstStr = srcStr.substr(start, end - start);
        if (!trimStr.empty())
        {
            dstStr.remove_prefix(dstStr.find_first_not_of(trimStr));
            dstStr.remove_suffix(
                dstStr.size() - 1 - dstStr.find_last_not_of(trimStr));
        }

        if (!dstStr.empty())
        {
            out.emplace_back(dstStr);
        }
    }

    return out;
}

std::string getCurrentSystemTime()
{
    const auto zonedTime{std::chrono::zoned_time{
        std::chrono::current_zone(), std::chrono::system_clock::now()}};
    return std::format("{:%F %Z %T}", zonedTime);
}

bool checkForFruPresence(const std::string& objPath)
{
    bool isPresent = false;
    try
    {
        auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
            objPath.c_str(), InventoryItem::property_names::present,
            InventoryItem::interface);
        isPresent = std::get<bool>(propVal);
    }
    catch (const sdbusplus::exception::internal_exception& e)
    {
        error("Failed to check for FRU presence at {PATH}, error - {ERROR}",
              "PATH", objPath, "ERROR", e);
    }
    return isPresent;
}

bool checkIfLogicalBitSet(const uint16_t& containerId)
{
    return !(containerId & 0x8000);
}

void setFruPresence(const std::string& fruObjPath, bool present)
{
    pldm::utils::PropertyValue value{present};
    pldm::utils::DBusMapping dbusMapping;
    dbusMapping.objectPath = fruObjPath;
    dbusMapping.interface = InventoryItem::interface;
    dbusMapping.propertyName = InventoryItem::property_names::present;
    dbusMapping.propertyType = "bool";
    try
    {
        pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to set the present property on path '{PATH}', error - {ERROR}.",
            "PATH", fruObjPath, "ERROR", e);
    }
}

std::string_view trimNameForDbus(std::string& name)
{
    std::replace(name.begin(), name.end(), ' ', '_');
    auto nullTerminatorPos = name.find('\0');
    if (nullTerminatorPos != std::string::npos)
    {
        name.erase(nullTerminatorPos);
    }
    return name;
}

bool dbusPropValuesToDouble(const std::string_view& type,
                            const pldm::utils::PropertyValue& value,
                            double* doubleValue)
{
    if (!dbusValueNumericTypeNames.contains(type))
    {
        return false;
    }

    if (!doubleValue)
    {
        return false;
    }

    try
    {
        if (type == "uint8_t")
        {
            *doubleValue = static_cast<double>(std::get<uint8_t>(value));
        }
        else if (type == "int16_t")
        {
            *doubleValue = static_cast<double>(std::get<int16_t>(value));
        }
        else if (type == "uint16_t")
        {
            *doubleValue = static_cast<double>(std::get<uint16_t>(value));
        }
        else if (type == "int32_t")
        {
            *doubleValue = static_cast<double>(std::get<int32_t>(value));
        }
        else if (type == "uint32_t")
        {
            *doubleValue = static_cast<double>(std::get<uint32_t>(value));
        }
        else if (type == "int64_t")
        {
            *doubleValue = static_cast<double>(std::get<int64_t>(value));
        }
        else if (type == "uint64_t")
        {
            *doubleValue = static_cast<double>(std::get<uint64_t>(value));
        }
        else if (type == "double")
        {
            *doubleValue = static_cast<double>(std::get<double>(value));
        }
        else
        {
            return false;
        }
    }
    catch (const std::exception& e)
    {
        return false;
    }

    return true;
}

std::optional<std::string> fruFieldValuestring(const uint8_t* value,
                                               const uint8_t& length)
{
    if (!value || !length)
    {
        return std::nullopt;
    }

    return std::string(reinterpret_cast<const char*>(value), length);
}

std::optional<uint32_t> fruFieldParserU32(const uint8_t* value,
                                          const uint8_t& length)
{
    if (!value || length != sizeof(uint32_t))
    {
        lg2::error("Fru data to u32 invalid data.");
        return std::nullopt;
    }

    uint32_t ret = 0;
    std::memcpy(&ret, value, length);
    return ret;
}

SensorPDRs getStateSensorPDRsByType(uint16_t entityType, const pldm_pdr* repo)
{
    uint8_t* outData = nullptr;
    uint32_t size{};
    const pldm_pdr_record* record = nullptr;
    SensorPDRs pdrs;

    if (repo)
    {
        while ((record = pldm_pdr_find_record_by_type(
                    repo, PLDM_STATE_SENSOR_PDR, record, &outData, &size)))
        {
            auto pdr = new (outData) pldm_state_sensor_pdr;
            if (pdr && pdr->entity_type == entityType)
            {
                pdrs.emplace_back(outData, outData + size);
            }
        }
    }

    return pdrs;
}

std::vector<pldm::pdr::SensorID> findSensorIds(
    const pldm_pdr* pdrRepo, uint16_t entityType, uint16_t entityInstance,
    uint16_t containerId)
{
    std::vector<uint16_t> sensorIDs;
    auto pdrs = getStateSensorPDRsByType(entityType, pdrRepo);

    for (const auto& pdr : pdrs)
    {
        auto sensorPdr =
            reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());

        if (sensorPdr && sensorPdr->entity_type == entityType &&
            sensorPdr->entity_instance == entityInstance &&
            sensorPdr->container_id == containerId)
        {
            sensorIDs.emplace_back(sensorPdr->sensor_id);
        }
    }

    return sensorIDs;
}

EffecterPDRs getStateEffecterPDRsByType(uint16_t entityType,
                                        const pldm_pdr* repo)
{
    uint8_t* outData = nullptr;
    uint32_t size{};
    const pldm_pdr_record* record = nullptr;
    EffecterPDRs pdrs;
    if (repo)
    {
        while ((record = pldm_pdr_find_record_by_type(
                    repo, PLDM_STATE_EFFECTER_PDR, record, &outData, &size)))
        {
            auto pdr = new (outData) pldm_state_effecter_pdr;
            if (pdr && pdr->entity_type == entityType)
            {
                pdrs.emplace_back(outData, outData + size);
            }
        }
    }
    return pdrs;
}

std::vector<pldm::pdr::EffecterID> findEffecterIds(
    const pldm_pdr* pdrRepo, uint16_t entityType, uint16_t entityInstance,
    uint16_t containerId)
{
    std::vector<uint16_t> effecterIDs;
    auto pdrs = getStateEffecterPDRsByType(entityType, pdrRepo);
    for (const auto& pdr : pdrs)
    {
        auto effecterPdr =
            reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
        if (effecterPdr && effecterPdr->entity_type == entityType &&
            effecterPdr->entity_instance == entityInstance &&
            effecterPdr->container_id == containerId)
        {
            effecterIDs.emplace_back(effecterPdr->effecter_id);
        }
    }
    return effecterIDs;
}

void setBiosAttr(const PendingAttributesList& biosAttrList)
{
    for (const auto& [attrName, biosAttrDetails] : biosAttrList)
    {
        auto& bus = DBusHandler::getBus();
        try
        {
            auto service = pldm::utils::DBusHandler().getService(
                biosConfigPath, BIOSConfigManager::interface);
            auto method =
                bus.new_method_call(service.c_str(), biosConfigPath,
                                    "org.freedesktop.DBus.Properties", "Set");
            method.append(BIOSConfigManager::interface,
                          BIOSConfigManager::property_names::pending_attributes,
                          std::variant<PendingAttributesList>(biosAttrList));
            bus.call_noreply(method, dbusTimeout);
        }
        catch (const sdbusplus::exception::internal_exception& e)
        {
            AttributeType attrType;
            AttributeValue attrValue;
            std::tie(attrType, attrValue) = biosAttrDetails;
            if (attrType ==
                "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer")
            {
                info(
                    "Error setting the value {VALUE} to bios attribute {BIOS_ATTR}: {ERR_EXCEP}",
                    "VALUE", std::get<int64_t>(attrValue), "BIOS_ATTR",
                    attrName, "ERR_EXCEP", e);
            }
            else
            {
                info(
                    "Error setting the value {VALUE} to bios attribute {BIOS_ATTR}: {ERR_EXCEP}",
                    "VALUE", std::get<std::string>(attrValue), "BIOS_ATTR",
                    attrName, "ERR_EXCEP", e);
            }
        }
    }
}

long int generateSwId()
{
    return random() % 10000;
}

} // namespace utils
} // namespace pldm
