#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_DBUS_UTILS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_DBUS_UTILS_H_

#include <algorithm>
#include <cstdint>
#include <functional>
#include <set>
#include <span>  // NOLINT
#include <string>
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>

#include "logging.hpp"
#include "dbus_utility.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/exception.hpp"
#include "sdbusplus/message/native_types.hpp"
// Remove unpack_properties header. Have to have this header
// now since there are other files indirectly depending on this header and they
// haven't been ported to g3 yet.
#include "sdbusplus/unpack_properties.hpp"  // NOLINT

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"  // NOLINT
#endif

namespace redfish {
namespace dbus_utils {

struct UnpackErrorPrinter {
  void operator()(const sdbusplus::UnpackErrorReason reason,
                  const std::string& property) const noexcept {
    BMCWEB_LOG_ERROR
        << "DBUS property error in property: " << property << ", reason: "
        << static_cast<std::underlying_type_t<sdbusplus::UnpackErrorReason>>(
               reason);
  }
};

inline void getPropertiesFromManagedObjects(
    const dbus::utility::ManagedObjectType& managedObjects,
    const std::string& objPath, const std::string& interface,
    dbus::utility::DBusPropertiesMap& properties) {
  for (const auto& object : managedObjects) {
    if (object.first.str != objPath) {
      continue;
    }

    for (const auto& interface_map : object.second) {
      if (interface_map.first != interface) {
        continue;
      }
      properties = interface_map.second;
    }
  }
}

// Populates |serviceNames| list with unique services found in the given
// subtree.
inline std::vector<std::string> getServiceNamesFromSubtree(
    const dbus::utility::MapperGetSubTreeResponse& subtree) {
  std::set<std::string> unique_service_names;
  for (const auto& [_, serviceMap] : subtree) {
    for (const auto& service_pair : serviceMap) {
      unique_service_names.insert(service_pair.first);
    }
  }
  return {unique_service_names.begin(), unique_service_names.end()};
}

// Checks if any one of given interfaces is present in the service map.
inline bool findInterfacesInServiceMap(
    const dbus::utility::MapperServiceMap& serviceMap,
    std::span<const std::string_view> interfaces) {
  for (const auto& [service_name, interfaceList] : serviceMap) {  // NOLINT
    if (std::find_first_of(interfaceList.begin(), interfaceList.end(),
                           interfaces.begin(),
                           interfaces.end()) != interfaceList.end()) {
      return true;
    }
  }
  return false;
}

/**
 * Recursively gets managed objects under given object path from each service in
 * the given list of service names and maps objects to the service name they
 * originate from.
 *
 * @param[in] serviceList               Mutable list of unique service names.
 * @param[in] objPath                   Managed objects are requested relative
 *                                      to this path.
 * @param[in,out] managed_objects_by_service   Service name to managed objects
 * map.
 * @param[in] callback                  Callback to execute after getting
 *                                      managed objects from all service names
 *                                      in the list.
 */
template <typename Callback>
inline void getManagedObjectsInEachServiceCallback(
    std::vector<std::string>&& serviceList,
    const sdbusplus::message::object_path& objPath,
    std::unordered_map<std::string, dbus::utility::ManagedObjectType>&&
        managed_objects_by_service,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  BMCWEB_LOG_DEBUG << "GetManagedObjects from next service in list.";
  if (serviceList.empty()) {
    BMCWEB_LOG_DEBUG << "Recieved managed objects from all services.";
    callback(managed_objects_by_service);
    return;
  }
  std::string service_name = serviceList.back();
  serviceList.pop_back();

  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      service_name, objPath, context,
      [serviceList{std::move(serviceList)}, service_name, objPath,
       managed_objects_by_service{std::move(managed_objects_by_service)},
       context = context, callback{std::forward<Callback>(callback)}](
          const boost::system::error_code& ec,
          const dbus::utility::ManagedObjectType& managedObjects) mutable {
        if (!ec) {
          managed_objects_by_service[service_name] = managedObjects;
        }
        getManagedObjectsInEachServiceCallback(
            std::move(serviceList), objPath,
            std::move(managed_objects_by_service), context,
            std::forward<decltype(callback)>(callback));
      });
}

/**
 * Gets managed objects under given object path from each service in the given
 * list of service names.
 *
 * @param[in] serviceList               Mutable list of unique service names.
 * @param[in] objPath                   Managed objects are requested relative
 *                                      to this path.
 * @param[in] callback                  Callback to execute after getting
 *                                      managed objects from all service names
 *                                      in the list.
 */
template <typename Callback>
inline void getManagedObjectsInEachService(
    std::vector<std::string>&& serviceList,
    const sdbusplus::message::object_path& objPath,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  BMCWEB_LOG_DEBUG << "Requesting managed objects from given list of "
                   << "services ";
  std::unordered_map<std::string, dbus::utility::ManagedObjectType>
      managed_objects_by_service;
  if (serviceList.empty()) {
    BMCWEB_LOG_ERROR << "Service list is empty";
    callback(managed_objects_by_service);
    return;
  }
  std::string service_name = serviceList.back();
  serviceList.pop_back();

  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      service_name, objPath, context,
      [serviceList{std::move(serviceList)}, service_name, objPath,
       managed_objects_by_service{std::move(managed_objects_by_service)},
       context = context, callback{std::forward<Callback>(callback)}](
          const boost::system::error_code& ec,
          const dbus::utility::ManagedObjectType& managedObjects) mutable {
        if (!ec) {
          managed_objects_by_service[service_name] = managedObjects;
        }
        getManagedObjectsInEachServiceCallback(
            std::move(serviceList), objPath,
            std::move(managed_objects_by_service), context,
            std::forward<decltype(callback)>(callback));
      });
}

template <typename PropertyType>
void getProperty(const std::string& service, const std::string& path,
                 const std::string& interface, const std::string& property,
                 const managedStore::ManagedObjectStoreContext& requestContext,
                 std::function<void(const boost::system::error_code&,
                                    const PropertyType&)>&& callback) {
  managedStore::KeyType key_type(managedStore::ManagedType::kManagedProperty,
                                service, {path}, interface, property);
  BMCWEB_LOG_STATEFUL_DEBUG << "getProperty: Key " << key_type.toString()
                            << " requestContext " << requestContext.toString();

  managedStore::GetManagedObjectStore()->getProperty(
      key_type, requestContext,
      [callback{std::move(callback)}](
          const boost::system::error_code& ec,
          const dbus::utility::DbusVariantType& managedProperty,
          [[maybe_unused]] uint64_t age_ms) {
        if (ec) {
          callback(ec, {});
          return;
        }
        const PropertyType* propertyValue =
            std::get_if<PropertyType>(&managedProperty);
        if (propertyValue) {
          callback(ec, *propertyValue);
          return;
        }
        callback(boost::system::errc::make_error_code(
                     boost::system::errc::invalid_argument),
                 {});
      });
}

template <typename PropertyType>
void getProperty(
    const std::string& service, const std::string& path,
    const std::string& interface, const std::string& property,
    const managedStore::ManagedObjectStoreContext& requestContext,
    std::function<void(const boost::system::error_code&, const PropertyType&,
                       uint64_t)>&& callback) {
  managedStore::KeyType key_type(managedStore::ManagedType::kManagedProperty,
                                service, {path}, interface, property);
  BMCWEB_LOG_STATEFUL_DEBUG << "getProperty: Key " << key_type.toString()
                            << " requestContext " << requestContext.toString();

  managedStore::GetManagedObjectStore()->getProperty(
      key_type, requestContext,
      [callback{std::move(callback)}](
          const boost::system::error_code& ec,
          const dbus::utility::DbusVariantType& managedProperty,
          uint64_t age_ms) {
        if (ec) {
          callback(ec, {}, 0);
          return;
        }
        const PropertyType* propertyValue =
            std::get_if<PropertyType>(&managedProperty);
        if (propertyValue) {
          callback(ec, *propertyValue, age_ms);
          return;
        }
        callback(boost::system::errc::make_error_code(
                     boost::system::errc::invalid_argument),
                 {}, 0);
      });
}

inline void getAssociationEndPoints(
    const std::string& path,
    const managedStore::ManagedObjectStoreContext& requestContext,
    std::function<void(const boost::system::error_code&,
                       const dbus::utility::MapperEndPoints&)>&& callback) {
  getProperty<dbus::utility::MapperEndPoints>(
      "xyz.openbmc_project.ObjectMapper", {path},
      "xyz.openbmc_project.Association", "endpoints", requestContext,
      std::move(callback));
}

template <typename Callback>
inline void checkDbusPathExists(
    const std::string& path,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  managedStore::GetManagedObjectStore()->getDbusObject(
      path, {}, context,
      [callback{std::forward<Callback>(callback)}](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetObject& objectNames) {
        callback(!ec && !objectNames.empty());
      });
}

template <typename Callback>
inline void getAssociatedSubTree(
    const sdbusplus::message::object_path& associatedPath,
    const sdbusplus::message::object_path& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  managedStore::GetManagedObjectStore()->getAssociatedSubTree(
      associatedPath, path, depth, interfaces, context,
      std::forward<Callback>(callback));
}

template <typename Callback>
inline void getAssociatedSubTreePaths(
    const sdbusplus::message::object_path& associatedPath,
    const sdbusplus::message::object_path& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
      associatedPath, path, depth, interfaces, context,
      std::forward<Callback>(callback));
}

template <typename Callback>
inline void getSubTree(const std::string& path, int32_t depth,
                       std::span<const std::string_view> interfaces,
                       const managedStore::ManagedObjectStoreContext& context,
                       Callback&& callback) {
  managedStore::GetManagedObjectStore()->getSubTree(
      path, depth, interfaces, context, std::forward<Callback>(callback));
}

// Overload to support span of strings for interface names.
template <typename Callback>
inline void getSubTree(const std::string& path, int32_t depth,
                       std::span<std::string> interfaces,
                       const managedStore::ManagedObjectStoreContext& context,
                       Callback&& callback) {
  managedStore::GetManagedObjectStore()->getSubTree(
      path, depth, interfaces, context, std::forward<Callback>(callback));
}

template <typename Callback>
inline void getSubTreePaths(
    const std::string& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      path, depth, interfaces, context, std::forward<Callback>(callback));
}

template <typename Callback>
inline void getManagedObjects(
    const std::string& service, const sdbusplus::message::object_path& path,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      service, path, context, std::forward<Callback>(callback));
}

template <typename Callback>
inline void getDbusObject(
    const std::string& path, std::span<const std::string_view> interfaces,
    const managedStore::ManagedObjectStoreContext& context,
    Callback&& callback) {
  managedStore::GetManagedObjectStore()->getDbusObject(
      path, interfaces, context, std::forward<Callback>(callback));
}

}  // namespace dbus_utils
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_DBUS_UTILS_H_
