#pragma once

#include "pmbus.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>

#include <string>

namespace phosphor
{
namespace power
{
namespace util
{

constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";

using DbusPath = std::string;
using DbusProperty = std::string;
using DbusService = std::string;
using DbusInterface = std::string;
using DbusInterfaceList = std::vector<DbusInterface>;
using DbusSubtree =
    std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;
using DbusVariant = std::variant<uint64_t, std::string, std::vector<uint64_t>>;
using DbusPropertyMap = std::map<DbusProperty, DbusVariant>;
/**
 * @brief Get the service name from the mapper for the
 *        interface and path passed in.
 *
 * @param[in] path - the D-Bus path name
 * @param[in] interface - the D-Bus interface name
 * @param[in] bus - the D-Bus object
 * @param[in] logError - log error when no service found
 *
 * @return The service name
 */
std::string getService(const std::string& path, const std::string& interface,
                       sdbusplus::bus::bus& bus, bool logError = true);

/**
 * @brief Read a D-Bus property
 *
 * @param[in] interface - the interface the property is on
 * @param[in] propertName - the name of the property
 * @param[in] path - the D-Bus path
 * @param[in] service - the D-Bus service
 * @param[in] bus - the D-Bus object
 * @param[out] value - filled in with the property value
 */
template <typename T>
void getProperty(const std::string& interface, const std::string& propertyName,
                 const std::string& path, const std::string& service,
                 sdbusplus::bus::bus& bus, T& value)
{
    std::variant<T> property;

    auto method = bus.new_method_call(service.c_str(), path.c_str(),
                                      PROPERTY_INTF, "Get");

    method.append(interface, propertyName);

    auto reply = bus.call(method);

    reply.read(property);
    value = std::get<T>(property);
}

/**
 * @brief Write a D-Bus property
 *
 * @param[in] interface - the interface the property is on
 * @param[in] propertName - the name of the property
 * @param[in] path - the D-Bus path
 * @param[in] service - the D-Bus service
 * @param[in] bus - the D-Bus object
 * @param[in] value - the value to set the property to
 */
template <typename T>
void setProperty(const std::string& interface, const std::string& propertyName,
                 const std::string& path, const std::string& service,
                 sdbusplus::bus::bus& bus, T& value)
{
    std::variant<T> propertyValue(value);

    auto method = bus.new_method_call(service.c_str(), path.c_str(),
                                      PROPERTY_INTF, "Set");

    method.append(interface, propertyName, propertyValue);

    auto reply = bus.call(method);
}

/**
 * @brief Get all D-Bus properties
 *
 * @param[in] bus - the D-Bus object
 * @param[in] path - the D-Bus object path
 * @param[in] interface - the D-Bus interface name
 * @param[in] service - the D-Bus service name (optional)
 *
 * @return DbusPropertyMap - Map of property names and values
 */
DbusPropertyMap getAllProperties(sdbusplus::bus::bus& bus,
                                 const std::string& path,
                                 const std::string& interface,
                                 const std::string& service = std::string());

/** @brief Get subtree from the object mapper.
 *
 * Helper function to find objects, services, and interfaces.
 * See:
 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
 *
 * @param[in] bus - The D-Bus object.
 * @param[in] path - The root of the tree to search.
 * @param[in] interface - Interface in the subtree to search for
 * @param[in] depth - The number of path elements to descend.
 *
 * @return DbusSubtree - Map of object paths to a map of service names to their
 *                       interfaces.
 */
DbusSubtree getSubTree(sdbusplus::bus::bus& bus, const std::string& path,
                       const std::string& interface, int32_t depth);

/**
 * Logs an error and powers off the system.
 *
 * @tparam T - error that will be logged before the power off
 * @param[in] bus - D-Bus object
 */
template <typename T>
void powerOff(sdbusplus::bus::bus& bus)
{
    phosphor::logging::report<T>();

    auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
                                      SYSTEMD_INTERFACE, "StartUnit");

    method.append(POWEROFF_TARGET);
    method.append("replace");

    bus.call_noreply(method);
}

/**
 * Load json from a file
 *
 * @param[in] path - The path of the json file
 *
 * @return The nlohmann::json object
 */
nlohmann::json loadJSONFromFile(const char* path);

/**
 * Get PmBus access type from the json config
 *
 * @param[in] json - The json object
 *
 * @return The pmbus access type
 */
phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json);

/**
 * Check if power is on
 *
 * @param[in] bus - D-Bus object
 * @param[in] defaultState - The default state if the function fails to get
 *                           the power state.
 *
 * @return true if power is on, otherwise false;
 *         defaultState if it fails to get the power state.
 */
bool isPoweredOn(sdbusplus::bus::bus& bus, bool defaultState = false);

/**
 * Get all PSU inventory paths from D-Bus
 *
 * @param[in] bus - D-Bus object
 *
 * @return The list of PSU inventory paths
 */
std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus::bus& bus);

} // namespace util
} // namespace power
} // namespace phosphor
