#pragma once

#include <sdbusplus/server.hpp>

#include <map>
#include <string>
#include <vector>

namespace ibm
{
namespace logging
{

using DbusInterface = std::string;
using DbusProperty = std::string;
using DbusService = std::string;
using DbusPath = std::string;

static constexpr auto forwardPos = 0;
static constexpr auto reversePos = 1;
static constexpr auto endpointPos = 2;
using AssociationsPropertyType =
    std::vector<std::tuple<std::string, std::string, std::string>>;

using Value = std::variant<bool, uint32_t, uint64_t, std::string,
                           std::vector<std::string>, AssociationsPropertyType>;

using DbusPropertyMap = std::map<DbusProperty, Value>;
using DbusInterfaceMap = std::map<DbusInterface, DbusPropertyMap>;
using DbusInterfaceList = std::vector<DbusInterface>;

using ObjectValueTree =
    std::map<sdbusplus::message::object_path, DbusInterfaceMap>;

using DbusSubtree =
    std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;

/**
 * Returns the managed objects for an object path and service
 *
 * Returns an empty map if there are any failures.
 *
 * @param[in] bus - the D-Bus object
 * @param[in] service - the D-Bus service name
 * @param[in] objPath - the D-Bus object path
 *
 * @return ObjectValueTree - A map of object paths to their
 *                           interfaces and properties.
 */
ObjectValueTree getManagedObjects(sdbusplus::bus_t& bus,
                                  const std::string& service,
                                  const std::string& objPath);

/**
 * Returns the subtree for a root, depth, and interface.
 *
 * Returns an empty map if there are any failures.
 *
 * @param[in] bus - the D-Bus object
 * @param[in] root - the point from which to provide results
 * @param[in] depth - the number of path elements to descend
 *
 * @return DbusSubtree - A map of object paths to their
 *                       services and interfaces.
 */
DbusSubtree getSubtree(sdbusplus::bus_t& bus, const std::string& root,
                       int depth, const std::string& interface);

/**
 * Get the D-Bus service name for the object path and interface from
 * the data returned from a GetSubTree call.
 *
 * Returns an empty string if the service can't be found.
 *
 * @param[in] objPath - the D-Bus object path
 * @param[in] interface - the D-Bus interface name
 * @param[in] tree - the D-Bus GetSubTree response
 *
 * @return string - the service name
 */
DbusService getService(const std::string& objPath, const std::string& interface,
                       const DbusSubtree& tree);

/**
 * Returns all properties on a particular interface on a
 * particular D-Bus object.
 *
 * Returns an empty map if there are any failures.
 *
 * @param[in] bus - the D-Bus object
 * @param[in] service - the D-Bus service name
 * @param[in] objPath - the D-Bus object path
 * @param[in] interface - the D-Bus interface name
 *
 * @return DbusPropertyMap - The map of property names to values
 */
DbusPropertyMap getAllProperties(sdbusplus::bus_t& bus,
                                 const std::string& service,
                                 const std::string& objPath,
                                 const std::string& interface);
} // namespace logging
} // namespace ibm
