#pragma once

#include "constants.hpp"
#include "exceptions.hpp"
#include "logger.hpp"
#include "types.hpp"

#include <chrono>

namespace vpd
{
/**
 * @brief The namespace defines utlity methods for generic D-Bus operations.
 */
namespace dbusUtility
{

/**
 * @brief An API to get Map of service and interfaces for an object path.
 *
 * The API returns a Map of service name and interfaces for a given pair of
 * object path and interface list. It can be used to determine service name
 * which implemets a particular object path and interface.
 *
 * Note: It will be caller's responsibility to check for empty map returned and
 * generate appropriate error.
 *
 * @param [in] objectPath - Object path under the service.
 * @param [in] interfaces - Array of interface(s).
 * @return - A Map of service name to object to interface(s), if success.
 *           If failed,  empty map.
 */
inline types::MapperGetObject getObjectMap(const std::string& objectPath,
                                           std::span<const char*> interfaces)
{
    types::MapperGetObject getObjectMap;

    // interface list is optional argument, hence no check required.
    if (objectPath.empty())
    {
        logging::logMessage("Path value is empty, invalid call to GetObject");
        return getObjectMap;
    }

    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto method = bus.new_method_call(
            "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "GetObject");

        method.append(objectPath, interfaces);
        auto result = bus.call(method);
        result.read(getObjectMap);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        // logging::logMessage(e.what());
        return getObjectMap;
    }

    return getObjectMap;
}

/**
 * @brief An API to get property map for an interface.
 *
 * This API returns a map of property and its value with respect to a particular
 * interface.
 *
 * Note: It will be caller's responsibility to check for empty map returned and
 * generate appropriate error.
 *
 * @param[in] i_service - Service name.
 * @param[in] i_objectPath - object path.
 * @param[in] i_interface - Interface, for the properties to be listed.
 *
 * @return - A map of property and value of an interface, if success.
 *           if failed, empty map.
 */
inline types::PropertyMap getPropertyMap(const std::string& i_service,
                                         const std::string& i_objectPath,
                                         const std::string& i_interface)
{
    types::PropertyMap l_propertyValueMap;
    if (i_service.empty() || i_objectPath.empty() || i_interface.empty())
    {
        logging::logMessage("Invalid parameters to get property map");
        return l_propertyValueMap;
    }

    try
    {
        auto l_bus = sdbusplus::bus::new_default();
        auto l_method =
            l_bus.new_method_call(i_service.c_str(), i_objectPath.c_str(),
                                  "org.freedesktop.DBus.Properties", "GetAll");
        l_method.append(i_interface);
        auto l_result = l_bus.call(l_method);
        l_result.read(l_propertyValueMap);
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage(l_ex.what());
    }

    return l_propertyValueMap;
}

/**
 * @brief API to get object subtree from D-bus.
 *
 * The API returns the map of object, services and interfaces in the
 * subtree that implement a certain interface. If no interfaces are provided
 * then all the objects, services and interfaces under the subtree will
 * be returned.
 *
 * Note: Depth can be 0 and interfaces can be null.
 * It will be caller's responsibility to check for empty vector returned
 * and generate appropriate error.
 *
 * @param[in] i_objectPath - Path to search for an interface.
 * @param[in] i_depth - Maximum depth of the tree to search.
 * @param[in] i_interfaces - List of interfaces to search.
 *
 * @return - A map of object and its related services and interfaces, if
 *           success. If failed, empty map.
 */

inline types::MapperGetSubTree getObjectSubTree(
    const std::string& i_objectPath, const int& i_depth,
    const std::vector<std::string>& i_interfaces)
{
    types::MapperGetSubTree l_subTreeMap;

    if (i_objectPath.empty())
    {
        logging::logMessage("Object path is empty.");
        return l_subTreeMap;
    }

    try
    {
        auto l_bus = sdbusplus::bus::new_default();
        auto l_method = l_bus.new_method_call(
            constants::objectMapperService, constants::objectMapperPath,
            constants::objectMapperInf, "GetSubTree");
        l_method.append(i_objectPath, i_depth, i_interfaces);
        auto l_result = l_bus.call(l_method);
        l_result.read(l_subTreeMap);
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage(l_ex.what());
    }

    return l_subTreeMap;
}

/**
 * @brief An API to read property from Dbus.
 *
 * The caller of the API needs to validate the validatity and correctness of the
 * type and value of data returned. The API will just fetch and retun the data
 * without any data validation.
 *
 * Note: It will be caller's responsibility to check for empty value returned
 * and generate appropriate error if required.
 *
 * @param [in] serviceName - Name of the Dbus service.
 * @param [in] objectPath - Object path under the service.
 * @param [in] interface - Interface under which property exist.
 * @param [in] property - Property whose value is to be read.
 * @return - Value read from Dbus, if success.
 *           If failed, empty variant.
 */
inline types::DbusVariantType readDbusProperty(
    const std::string& serviceName, const std::string& objectPath,
    const std::string& interface, const std::string& property)
{
    types::DbusVariantType propertyValue;

    // Mandatory fields to make a read dbus call.
    if (serviceName.empty() || objectPath.empty() || interface.empty() ||
        property.empty())
    {
        logging::logMessage(
            "One of the parameter to make Dbus read call is empty.");
        return propertyValue;
    }

    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto method =
            bus.new_method_call(serviceName.c_str(), objectPath.c_str(),
                                "org.freedesktop.DBus.Properties", "Get");
        method.append(interface, property);

        auto result = bus.call(method);
        result.read(propertyValue);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        return propertyValue;
    }
    return propertyValue;
}

/**
 * @brief An API to write property on Dbus.
 *
 * The caller of this API needs to handle exception thrown by this method to
 * identify any write failure. The API in no other way indicate write  failure
 * to the caller.
 *
 * @param [in] serviceName - Name of the Dbus service.
 * @param [in] objectPath - Object path under the service.
 * @param [in] interface - Interface under which property exist.
 * @param [in] property - Property whose value is to be written.
 * @param [in] propertyValue - The value to be written.
 * @return True if write on DBus is success, false otherwise.
 */
inline bool writeDbusProperty(
    const std::string& serviceName, const std::string& objectPath,
    const std::string& interface, const std::string& property,
    const types::DbusVariantType& propertyValue)
{
    try
    {
        // Mandatory fields to make a write dbus call.
        if (serviceName.empty() || objectPath.empty() || interface.empty() ||
            property.empty())
        {
            throw std::runtime_error("Dbus write failed, Parameter empty");
        }

        auto bus = sdbusplus::bus::new_default();
        auto method =
            bus.new_method_call(serviceName.c_str(), objectPath.c_str(),
                                "org.freedesktop.DBus.Properties", "Set");
        method.append(interface, property, propertyValue);
        bus.call(method);

        return true;
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "DBus write failed, error: " + std::string(l_ex.what()));
        return false;
    }
}

/**
 * @brief API to publish data on PIM
 *
 * The API calls notify on PIM object to publlish VPD.
 *
 * @param[in] objectMap - Object, its interface and data.
 * @return bool - Status of call to PIM notify.
 */
inline bool callPIM(types::ObjectMap&& objectMap)
{
    try
    {
        for (const auto& l_objectKeyValue : objectMap)
        {
            auto l_nodeHandle = objectMap.extract(l_objectKeyValue.first);

            if (l_nodeHandle.key().str.find(constants::pimPath, 0) !=
                std::string::npos)
            {
                l_nodeHandle.key() = l_nodeHandle.key().str.replace(
                    0, std::strlen(constants::pimPath), "");
                objectMap.insert(std::move(l_nodeHandle));
            }
        }

        auto bus = sdbusplus::bus::new_default();
        auto pimMsg =
            bus.new_method_call(constants::pimServiceName, constants::pimPath,
                                constants::pimIntf, "Notify");
        pimMsg.append(std::move(objectMap));
        bus.call(pimMsg);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        return false;
    }
    return true;
}

/**
 * @brief API to check if a D-Bus service is running or not.
 *
 * Any failure in calling the method "NameHasOwner" implies that the service is
 * not in a running state. Hence the API returns false in case of any exception
 * as well.
 *
 * @param[in] i_serviceName - D-Bus service name whose status is to be checked.
 * @return bool - True if the service is running, false otherwise.
 */
inline bool isServiceRunning(const std::string& i_serviceName)
{
    bool l_retVal = false;

    try
    {
        auto l_bus = sdbusplus::bus::new_default();
        auto l_method = l_bus.new_method_call(
            "org.freedesktop.DBus", "/org/freedesktop/DBus",
            "org.freedesktop.DBus", "NameHasOwner");
        l_method.append(i_serviceName);

        l_bus.call(l_method).read(l_retVal);
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage(
            "Call to check service status failed with exception: " +
            std::string(l_ex.what()));
    }

    return l_retVal;
}

/**
 * @brief API to call "GetAttribute" method uner BIOS manager.
 *
 * The API reads the given attribuute from BIOS and returns a tuple of both
 * current as well as pending value for that attribute.
 * The API return only the current attribute value if found.
 * API returns an empty variant of type BiosAttributeCurrentValue in case of any
 * error.
 *
 * @param[in] i_attributeName - Attribute to be read.
 * @return Tuple of PLDM attribute Type, current attribute value and pending
 * attribute value.
 */
inline types::BiosAttributeCurrentValue biosGetAttributeMethodCall(
    const std::string& i_attributeName) noexcept
{
    types::BiosGetAttrRetType l_attributeVal;
    try
    {
        auto l_bus = sdbusplus::bus::new_default();
        auto l_method = l_bus.new_method_call(
            constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
            constants::biosConfigMgrInterface, "GetAttribute");
        l_method.append(i_attributeName);

        auto l_result = l_bus.call(l_method);
        l_result.read(std::get<0>(l_attributeVal), std::get<1>(l_attributeVal),
                      std::get<2>(l_attributeVal));
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage(
            "Failed to read BIOS Attribute: " + i_attributeName +
            " due to error " + std::string(l_ex.what()));

        // TODO: Log an informational PEL here.
    }

    return std::get<1>(l_attributeVal);
}

/**
 * @brief API to check if Chassis is powered on.
 *
 * This API queries Phosphor Chassis State Manager to know whether
 * Chassis is powered on.
 *
 * @return true if chassis is powered on, false otherwise
 */
inline bool isChassisPowerOn()
{
    auto powerState = dbusUtility::readDbusProperty(
        "xyz.openbmc_project.State.Chassis",
        "/xyz/openbmc_project/state/chassis0",
        "xyz.openbmc_project.State.Chassis", "CurrentPowerState");

    if (auto curPowerState = std::get_if<std::string>(&powerState))
    {
        if ("xyz.openbmc_project.State.Chassis.PowerState.On" == *curPowerState)
        {
            return true;
        }
        return false;
    }

    /*
        TODO: Add PEL.
        Callout: Firmware callout
        Type: Informational
        Description: Chassis state can't be determined, defaulting to chassis
        off. : e.what()
    */
    return false;
}

/**
 * @brief API to check if host is in running state.
 *
 * This API reads the current host state from D-bus and returns true if the host
 * is running.
 *
 * @return true if host is in running state. false otherwise.
 */
inline bool isHostRunning()
{
    const auto l_hostState = dbusUtility::readDbusProperty(
        constants::hostService, constants::hostObjectPath,
        constants::hostInterface, "CurrentHostState");

    if (const auto l_currHostState = std::get_if<std::string>(&l_hostState))
    {
        if (*l_currHostState == constants::hostRunningState)
        {
            return true;
        }
    }

    return false;
}

/**
 * @brief API to check if BMC is in ready state.
 *
 * This API reads the current state of BMC from D-bus and returns true if BMC is
 * in ready state.
 *
 * @return true if BMC is ready, false otherwise.
 */
inline bool isBMCReady()
{
    const auto l_bmcState = dbusUtility::readDbusProperty(
        constants::bmcStateService, constants::bmcZeroStateObject,
        constants::bmcStateInterface, constants::currentBMCStateProperty);

    if (const auto l_currBMCState = std::get_if<std::string>(&l_bmcState))
    {
        if (*l_currBMCState == constants::bmcReadyState)
        {
            return true;
        }
    }

    return false;
}

/**
 * @brief An API to enable BMC reboot guard
 *
 * This API does a D-Bus method call to enable BMC reboot guard.
 *
 * @return On success, returns 0, otherwise returns -1.
 */
inline int EnableRebootGuard() noexcept
{
    int l_rc{constants::FAILURE};
    try
    {
        auto l_bus = sdbusplus::bus::new_default();
        auto l_method = l_bus.new_method_call(
            constants::systemdService, constants::systemdObjectPath,
            constants::systemdManagerInterface, "StartUnit");
        l_method.append("reboot-guard-enable.service", "replace");
        l_bus.call_noreply(l_method);
        l_rc = constants::SUCCESS;
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        std::string l_errMsg =
            "D-Bus call to enable BMC reboot guard failed for reason: ";
        l_errMsg += l_ex.what();

        logging::logMessage(l_errMsg);
    }
    return l_rc;
}

/**
 * @brief An API to disable BMC reboot guard
 *
 * This API disables BMC reboot guard. This API has an inbuilt re-try mechanism.
 * If Disable Reboot Guard fails, this API attempts to Disable Reboot Guard for
 * 3 more times at an interval of 333ms.
 *
 * @return On success, returns 0, otherwise returns -1.
 */
inline int DisableRebootGuard() noexcept
{
    int l_rc{constants::FAILURE};

    // A lambda which executes the DBus call to disable BMC reboot guard.
    auto l_executeDisableRebootGuard = []() -> int {
        int l_dBusCallRc{constants::FAILURE};
        try
        {
            auto l_bus = sdbusplus::bus::new_default();
            auto l_method = l_bus.new_method_call(
                constants::systemdService, constants::systemdObjectPath,
                constants::systemdManagerInterface, "StartUnit");
            l_method.append("reboot-guard-disable.service", "replace");
            l_bus.call_noreply(l_method);
            l_dBusCallRc = constants::SUCCESS;
        }
        catch (const sdbusplus::exception::SdBusError& l_ex)
        {}
        return l_dBusCallRc;
    };

    if (constants::FAILURE == l_executeDisableRebootGuard())
    {
        std::function<void()> l_retryDisableRebootGuard;

        // A lambda which tries to disable BMC reboot guard for 3 times at an
        // interval of 333 ms.
        l_retryDisableRebootGuard = [&]() {
            constexpr int MAX_RETRIES{3};
            static int l_numRetries{0};

            if (l_numRetries < MAX_RETRIES)
            {
                l_numRetries++;
                if (constants::FAILURE == l_executeDisableRebootGuard())
                {
                    // sleep for 333ms before next retry. This is just a random
                    // value so that 3 re-tries * 333ms takes ~1 second in the
                    // worst case.
                    const std::chrono::milliseconds l_sleepTime{333};
                    std::this_thread::sleep_for(l_sleepTime);
                    l_retryDisableRebootGuard();
                }
                else
                {
                    l_numRetries = 0;
                    l_rc = constants::SUCCESS;
                }
            }
            else
            {
                // Failed to Disable Reboot Guard even after 3 retries.
                logging::logMessage("Failed to Disable Reboot Guard after " +
                                    std::to_string(MAX_RETRIES) + " re-tries");
                l_numRetries = 0;
            }
        };

        l_retryDisableRebootGuard();
    }
    else
    {
        l_rc = constants::SUCCESS;
    }
    return l_rc;
}

/**
 * @brief API to notify FRU VPD Collection status.
 *
 * This API uses PIM's Notify method to update the given FRU VPD collection
 * status on D-bus.
 *
 * @param[in] i_inventoryPath - D-bus inventory path
 * @param[in] i_fruCollectionStatus - FRU VPD collection status.
 *
 * @return true if update succeeds, false otherwise.
 */
inline bool notifyFRUCollectionStatus(const std::string& i_inventoryPath,
                                      const std::string& i_fruCollectionStatus)
{
    types::ObjectMap l_objectMap;
    types::InterfaceMap l_interfaceMap;
    types::PropertyMap l_propertyMap;

    l_propertyMap.emplace("CollectionStatus", i_fruCollectionStatus);
    l_interfaceMap.emplace(constants::vpdCollectionInterface, l_propertyMap);
    l_objectMap.emplace(i_inventoryPath, l_interfaceMap);

    if (!dbusUtility::callPIM(std::move(l_objectMap)))
    {
        return false;
    }

    return true;
}

/**
 * @brief API to read IM keyword from Dbus.
 *
 * @return IM value read from Dbus, Empty in case of any error.
 */
inline types::BinaryVector getImFromDbus()
{
    const auto& l_retValue = dbusUtility::readDbusProperty(
        constants::pimServiceName, constants::systemVpdInvPath,
        constants::vsbpInf, constants::kwdIM);

    auto l_imValue = std::get_if<types::BinaryVector>(&l_retValue);
    if (!l_imValue || (*l_imValue).size() != constants::VALUE_4)
    {
        return types::BinaryVector{};
    }

    return *l_imValue;
}

/**
 * @brief API to return prefix of functional firmware image.
 *
 * Every functional image belongs to a series which is denoted by the first two
 * characters of the image name. The API extracts that and returns it to the
 * caller.
 *
 * @return Two character string, empty string in case of any error.
 */
inline std::string getImagePrefix()
{
    try
    {
        types::DbusVariantType l_retVal = readDbusProperty(
            constants::objectMapperService, constants::functionalImageObjPath,
            constants::associationInterface, "endpoints");

        auto l_listOfFunctionalPath =
            std::get_if<std::vector<std::string>>(&l_retVal);

        if (!l_listOfFunctionalPath || (*l_listOfFunctionalPath).empty())
        {
            throw DbusException("failed to get functional image path.");
        }

        for (const auto& l_imagePath : *l_listOfFunctionalPath)
        {
            types::DbusVariantType l_retValPriority =
                readDbusProperty(constants::imageUpdateService, l_imagePath,
                                 constants::imagePrirotyInf, "Priority");

            auto l_imagePriority = std::get_if<uint8_t>(&l_retValPriority);
            if (!l_imagePriority)
            {
                throw DbusException(
                    "failed to read functional image priority for path [" +
                    l_imagePath + "]");
            }

            // only interested in running image.
            if (*l_imagePriority != constants::VALUE_0)
            {
                continue;
            }

            types::DbusVariantType l_retExVer = readDbusProperty(
                constants::imageUpdateService, l_imagePath,
                constants::imageExtendedVerInf, "ExtendedVersion");

            auto l_imageExtendedVersion = std::get_if<std::string>(&l_retExVer);
            if (!l_imageExtendedVersion)
            {
                throw DbusException(
                    "Unable to read extended version for the functional image [" +
                    l_imagePath + "]");
            }

            if ((*l_imageExtendedVersion).empty() ||
                (*l_imageExtendedVersion).length() <= constants::VALUE_2)
            {
                throw DbusException("Invalid extended version read for path [" +
                                    l_imagePath + "]");
            }

            // return first two character from image name.
            return (*l_imageExtendedVersion)
                .substr(constants::VALUE_0, constants::VALUE_2);
        }
        throw std::runtime_error("No Image found with required priority.");
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(l_ex.what());
        return std::string{};
    }
}

/**
 * @brief API to read DBus present property for the given inventory.
 *
 * @param[in] i_invObjPath - Inventory path.
 * @return Present property value, false in case of any error.
 */
inline bool isInventoryPresent(const std::string& i_invObjPath)
{
    if (i_invObjPath.empty())
    {
        return false;
    }

    const auto& l_retValue =
        dbusUtility::readDbusProperty(constants::pimServiceName, i_invObjPath,
                                      constants::inventoryItemInf, "Present");

    auto l_ptrPresence = std::get_if<bool>(&l_retValue);
    if (!l_ptrPresence)
    {
        return false;
    }

    return (*l_ptrPresence);
}

/**
 * @brief API to get list of sub tree paths for a given object path
 *
 * Given a DBus object path, this API returns a list of object paths under that
 * object path in the DBus tree. This API calls DBus method GetSubTreePaths
 * hosted by ObjectMapper DBus service.
 *
 * @param[in] i_objectPath - DBus object path.
 * @param[in] i_depth - The maximum subtree depth for which results should be
 * fetched. For unconstrained fetches use a depth of zero.
 * @param[in] i_constrainingInterfaces - An array of result set constraining
 * interfaces.
 *
 * @return On success, returns a std::vector<std::string> of object paths,
 * else returns an empty vector.
 *
 * Note: The caller of this API should check for empty vector.
 */
inline std::vector<std::string> GetSubTreePaths(
    const std::string i_objectPath, const int i_depth = 0,
    const std::vector<std::string>& i_constrainingInterfaces = {}) noexcept
{
    std::vector<std::string> l_objectPaths;
    try
    {
        auto l_bus = sdbusplus::bus::new_default();
        auto l_method = l_bus.new_method_call(
            constants::objectMapperService, constants::objectMapperPath,
            constants::objectMapperInf, "GetSubTreePaths");

        l_method.append(i_objectPath, i_depth, i_constrainingInterfaces);

        auto l_result = l_bus.call(l_method);
        l_result.read(l_objectPaths);
    }
    catch (const sdbusplus::exception::SdBusError& l_ex)
    {
        logging::logMessage(
            "Error while getting GetSubTreePaths for path [" + i_objectPath +
            "], error: " + std::string(l_ex.what()));
    }
    return l_objectPaths;
}

/**
 * @brief API to get Dbus service name for given connection identifier.
 *
 * @param[in] i_connectionId - Dbus connection ID.
 *
 * @return On success, returns the DBus service associated with given connection
 * ID, empty string otherwise.
 */
inline std::string getServiceNameFromConnectionId(
    [[maybe_unused]] const std::string& i_connectionId) noexcept
{
    std::string l_serviceName;
    try
    {
        if (i_connectionId.empty())
        {
            throw std::runtime_error("Empty connection ID");
        }

        /* TODO:
        - get PID corresponding to the connection ID
        - use PID to get corresponding encoded service name string
        - decode service name string */
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Failed to get service name from connection ID: [" +
            i_connectionId + "]. error: " + std::string(l_ex.what()));
    }
    return l_serviceName;
}
} // namespace dbusUtility
} // namespace vpd
