#pragma once

#include <boost/system/error_code.hpp>
#include <ipmid/api-types.hpp>
#include <ipmid/message.hpp>
#include <ipmid/types.hpp>
#include <sdbusplus/server.hpp>

#include <chrono>
#include <optional>

namespace ipmi
{

using namespace std::literals::chrono_literals;

constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";

constexpr auto ROOT = "/";
constexpr auto HOST_MATCH = "host0";

constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
constexpr auto DELETE_INTERFACE = "xyz.openbmc_project.Object.Delete";

constexpr auto METHOD_GET = "Get";
constexpr auto METHOD_GET_ALL = "GetAll";
constexpr auto METHOD_SET = "Set";

/* Use a value of 5s which aligns with BT/KCS bridged timeouts, rather
 * than the default 25s D-Bus timeout. */
constexpr std::chrono::microseconds IPMI_DBUS_TIMEOUT = 5s;

/** @class ServiceCache
 *  @brief Caches lookups of service names from the object mapper.
 *  @details Most ipmi commands need to talk to other dbus daemons to perform
 *           their intended actions on the BMC. This usually means they will
 *           first look up the service name providing the interface they
 *           require. This class reduces the number of such calls by caching
 *           the lookup for a specific service.
 */
class ServiceCache
{
  public:
    /** @brief Creates a new service cache for the given interface
     *         and path.
     *
     *  @param[in] intf - The interface used for each lookup
     *  @param[in] path - The path used for each lookup
     */
    ServiceCache(const std::string& intf, const std::string& path);
    ServiceCache(std::string&& intf, std::string&& path);

    /** @brief Gets the service name from the cache or does in a
     *         lookup when invalid.
     *
     *  @param[in] bus - The bus associated with and used for looking
     *                   up the service.
     */
    const std::string& getService(sdbusplus::bus_t& bus);

    /** @brief Invalidates the current service name */
    void invalidate();

    /** @brief A wrapper around sdbusplus bus.new_method_call
     *
     *  @param[in] bus - The bus used for calling the method
     *  @param[in] intf - The interface containing the method
     *  @param[in] method - The method name
     *  @return The message containing the method call.
     */
    sdbusplus::message_t newMethodCall(sdbusplus::bus_t& bus, const char* intf,
                                       const char* method);

    /** @brief Check to see if the current cache is valid
     *
     * @param[in] bus - The bus used for the service lookup
     * @return True if the cache is valid false otherwise.
     */
    bool isValid(sdbusplus::bus_t& bus) const;

  private:
    /** @brief DBUS interface provided by the service */
    const std::string intf;
    /** @brief DBUS path provided by the service */
    const std::string path;
    /** @brief The name of the service if valid */
    std::optional<std::string> cachedService;
    /** @brief The name of the bus used in the service lookup */
    std::optional<std::string> cachedBusName;
};

/**
 * @brief Get the DBUS Service name for the input dbus path
 *
 * @param[in] bus - DBUS Bus Object
 * @param[in] intf - DBUS Interface
 * @param[in] path - DBUS Object Path
 *
 */
std::string getService(sdbusplus::bus_t& bus, const std::string& intf,
                       const std::string& path);

/** @brief Gets the dbus sub tree implementing the given interface.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] interfaces - Dbus interface.
 *  @param[in] subtreePath - subtree from where the search should start.
 *  @param[in] depth - Search depth
 *  @return map of object path and service info.
 */
ObjectTree getSubTree(sdbusplus::bus_t& bus, const InterfaceList& interface,
                      const std::string& subtreePath = ROOT, int32_t depth = 0);

/** @brief Gets the dbus object info implementing the given interface
 *         from the given subtree.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] interface - Dbus interface.
 *  @param[in] subtreePath - subtree from where the search should start.
 *  @param[in] match - identifier for object.
 *  @return On success returns the object having objectpath and servicename.
 */
DbusObjectInfo getDbusObject(
    sdbusplus::bus_t& bus, const std::string& interface,
    const std::string& subtreePath = ROOT, const std::string& match = {});

/** @brief Gets the value associated with the given object
 *         and the interface.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] service - Dbus service name.
 *  @param[in] objPath - Dbus object path.
 *  @param[in] interface - Dbus interface.
 *  @param[in] property - name of the property.
 *  @return On success returns the value of the property.
 */
Value getDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
                      const std::string& objPath, const std::string& interface,
                      const std::string& property,
                      std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);

/** @brief Gets all the properties associated with the given object
 *         and the interface.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] service - Dbus service name.
 *  @param[in] objPath - Dbus object path.
 *  @param[in] interface - Dbus interface.
 *  @return On success returns the map of name value pair.
 */
PropertyMap getAllDbusProperties(
    sdbusplus::bus_t& bus, const std::string& service,
    const std::string& objPath, const std::string& interface,
    std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);

/** @brief Gets all managed objects associated with the given object
 *         path and service.
 *  @param[in] bus - D-Bus Bus Object.
 *  @param[in] service - D-Bus service name.
 *  @param[in] objPath - D-Bus object path.
 *  @return On success returns the map of name value pair.
 */
ObjectValueTree getManagedObjects(sdbusplus::bus_t& bus,
                                  const std::string& service,
                                  const std::string& objPath);

/** @brief Sets the property value of the given object.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] service - Dbus service name.
 *  @param[in] objPath - Dbus object path.
 *  @param[in] interface - Dbus interface.
 *  @param[in] property - name of the property.
 *  @param[in] value - value which needs to be set.
 */
void setDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
                     const std::string& objPath, const std::string& interface,
                     const std::string& property, const Value& value,
                     std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);

/** @brief  Gets all the dbus objects from the given service root
 *          which matches the object identifier.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] serviceRoot - Service root path.
 *  @param[in] interface - Dbus interface.
 *  @param[in] match - Identifier for a path.
 *  @returns map of object path and service info.
 */
ObjectTree getAllDbusObjects(
    sdbusplus::bus_t& bus, const std::string& serviceRoot,
    const std::string& interface, const std::string& match = {});

/** @brief Deletes all the dbus objects from the given service root
           which matches the object identifier.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] serviceRoot - Service root path.
 *  @param[in] interface - Dbus interface.
 *  @param[in] match - Identifier for object.
 */
void deleteAllDbusObjects(sdbusplus::bus_t& bus, const std::string& serviceRoot,
                          const std::string& interface,
                          const std::string& match = {})
    __attribute__((deprecated));

/** @brief Gets the ancestor objects of the given object
           which implements the given interface.
 *  @param[in] bus - Dbus bus object.
 *  @param[in] path - Child Dbus object path.
 *  @param[in] interfaces - Dbus interface list.
 *  @return map of object path and service info.
 */
ObjectTree getAllAncestors(sdbusplus::bus_t& bus, const std::string& path,
                           InterfaceList&& interfaces)
    __attribute__((deprecated));

/********* Begin co-routine yielding alternatives ***************/

/** @brief Get the D-Bus Service name for the input D-Bus path
 *
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] intf - D-Bus Interface
 *  @param[in] path - D-Bus Object Path
 *  @param[out] service - requested service name
 *  @return boost error code
 *
 */
boost::system::error_code
    getService(Context::ptr ctx, const std::string& intf,
               const std::string& path, std::string& service);

/** @brief Gets the dbus sub tree implementing the given interface.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] interfaces - Dbus interface.
 *  @param[in] subtreePath - subtree from where the search should start.
 *  @param[in] depth - Search depth
 *  @param[out] objectTree - map of object path and service info.
 *  @return map of object path and service info.
 */
boost::system::error_code getSubTree(
    Context::ptr ctx, const InterfaceList& interface,
    const std::string& subtreePath, int32_t depth, ObjectTree& objectTree);

/** @brief Gets the D-Bus object info implementing the given interface
 *         from the given subtree.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] interface - D-Bus interface.
 *  @param[in][optional] subtreePath - subtree from where the search starts.
 *  @param[in][optional] match - identifier for object.
 *  @param[out] D-Bus object with path and service name
 *  @return - boost error code object
 */
boost::system::error_code
    getDbusObject(Context::ptr ctx, const std::string& interface,
                  const std::string& subtreePath, const std::string& match,
                  DbusObjectInfo& dbusObject);

// default for ROOT for subtreePath and std::string{} for match
static inline boost::system::error_code getDbusObject(
    Context::ptr ctx, const std::string& interface, DbusObjectInfo& dbusObject)
{
    return getDbusObject(ctx, interface, ROOT, {}, dbusObject);
}

// default std::string{} for match
static inline boost::system::error_code
    getDbusObject(Context::ptr ctx, const std::string& interface,
                  const std::string& subtreePath, DbusObjectInfo& dbusObject)
{
    return getDbusObject(ctx, interface, subtreePath, {}, dbusObject);
}

/** @brief Gets the value associated with the given object
 *         and the interface.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] service - D-Bus service name.
 *  @param[in] objPath - D-Bus object path.
 *  @param[in] interface - D-Bus interface.
 *  @param[in] property - name of the property.
 *  @param[out] propertyValue - value of the D-Bus property.
 *  @return - boost error code object
 */
template <typename Type>
boost::system::error_code
    getDbusProperty(Context::ptr ctx, const std::string& service,
                    const std::string& objPath, const std::string& interface,
                    const std::string& property, Type& propertyValue)
{
    boost::system::error_code ec;
    auto variant = ctx->bus->yield_method_call<std::variant<Type>>(
        ctx->yield, ec, service.c_str(), objPath.c_str(), PROP_INTF, METHOD_GET,
        interface, property);
    if (!ec)
    {
        Type* tmp = std::get_if<Type>(&variant);
        if (tmp)
        {
            propertyValue = *tmp;
            return ec;
        }
        // user requested incorrect type; make an error code for them
        ec = boost::system::errc::make_error_code(
            boost::system::errc::invalid_argument);
    }
    return ec;
}

/** @brief Gets all the properties associated with the given object
 *         and the interface.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] service - D-Bus service name.
 *  @param[in] objPath - D-Bus object path.
 *  @param[in] interface - D-Bus interface.
 *  @param[out] properties - map of name value pair.
 *  @return - boost error code object
 */
boost::system::error_code getAllDbusProperties(
    Context::ptr ctx, const std::string& service, const std::string& objPath,
    const std::string& interface, PropertyMap& properties);

/** @brief Sets the property value of the given object.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] service - D-Bus service name.
 *  @param[in] objPath - D-Bus object path.
 *  @param[in] interface - D-Bus interface.
 *  @param[in] property - name of the property.
 *  @param[in] value - value which needs to be set.
 *  @return - boost error code object
 */
boost::system::error_code
    setDbusProperty(Context::ptr ctx, const std::string& service,
                    const std::string& objPath, const std::string& interface,
                    const std::string& property, const Value& value);

/** @brief  Gets all the D-Bus objects from the given service root
 *          which matches the object identifier.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] serviceRoot - Service root path.
 *  @param[in] interface - D-Bus interface.
 *  @param[in][optional] match - Identifier for a path.
 *  @param[out] objectree - map of object path and service info.
 *  @return - boost error code object
 */
boost::system::error_code
    getAllDbusObjects(Context::ptr ctx, const std::string& serviceRoot,
                      const std::string& interface, const std::string& match,
                      ObjectTree& objectTree);

// default std::string{} for match
static inline boost::system::error_code
    getAllDbusObjects(Context::ptr ctx, const std::string& serviceRoot,
                      const std::string& interface, ObjectTree& objectTree)
{
    return getAllDbusObjects(ctx, serviceRoot, interface, {}, objectTree);
}

/** @brief Deletes all the D-Bus objects from the given service root
           which matches the object identifier.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[out] ec - boost error code object
 *  @param[in] serviceRoot - Service root path.
 *  @param[in] interface - D-Bus interface.
 *  @param[in] match - Identifier for object.
 */
boost::system::error_code deleteAllDbusObjects(
    Context::ptr ctx, const std::string& serviceRoot,
    const std::string& interface, const std::string& match = {})
    __attribute__((deprecated));

/** @brief Gets all managed objects associated with the given object
 *         path and service.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] service - D-Bus service name.
 *  @param[in] objPath - D-Bus object path.
 *  @param[out] objects - map of name value pair.
 *  @return - boost error code object
 */
boost::system::error_code
    getManagedObjects(Context::ptr ctx, const std::string& service,
                      const std::string& objPath, ObjectValueTree& objects);

/** @brief Gets the ancestor objects of the given object
           which implements the given interface.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] path - Child D-Bus object path.
 *  @param[in] interfaces - D-Bus interface list.
 *  @param[out] ObjectTree - map of object path and service info.
 *  @return - boost error code object
 */
boost::system::error_code
    getAllAncestors(Context::ptr ctx, const std::string& path,
                    const InterfaceList& interfaces, ObjectTree& objectTree)
        __attribute__((deprecated));

/** @brief Gets the value associated with the given object
 *         and the interface.
 *  @param[in] ctx - ipmi::Context::ptr
 *  @param[in] service - D-Bus service name.
 *  @param[in] objPath - D-Bus object path.
 *  @param[in] interface - D-Bus interface.
 *  @param[in] method - name of the method.
 *  @return - boost error code object
 */

boost::system::error_code callDbusMethod(
    Context::ptr ctx, const std::string& service, const std::string& objPath,
    const std::string& interface, const std::string& method);

/********* End co-routine yielding alternatives ***************/

/** @brief Retrieve the value from map of variants,
 *         returning a default if the key does not exist or the
 *         type of the value does not match the expected type
 *
 *  @tparam T - type of expected value to return
 *  @param[in] props - D-Bus propery map (Map of variants)
 *  @param[in] name - key name of property to fetch
 *  @param[in] defaultValue - default value to return on error
 *  @return - value from propery map at name, or defaultValue
 */
template <typename T>
T mappedVariant(const ipmi::PropertyMap& props, const std::string& name,
                const T& defaultValue)
{
    auto item = props.find(name);
    if (item == props.end())
    {
        return defaultValue;
    }
    const T* prop = std::get_if<T>(&item->second);
    if (!prop)
    {
        return defaultValue;
    }
    return *prop;
}

/** @struct VariantToDoubleVisitor
 *  @brief Visitor to convert variants to doubles
 *  @details Performs a static cast on the underlying type
 */
struct VariantToDoubleVisitor
{
    template <typename T>
    std::enable_if_t<std::is_arithmetic<T>::value, double>
        operator()(const T& t) const
    {
        return static_cast<double>(t);
    }

    template <typename T>
    std::enable_if_t<!std::is_arithmetic<T>::value, double>
        operator()(const T&) const
    {
        throw std::invalid_argument("Cannot translate type to double");
    }
};

namespace method_no_args
{

/** @brief Calls the Dbus method which waits for response.
 *  @param[in] bus - DBUS Bus Object.
 *  @param[in] service - Dbus service name.
 *  @param[in] objPath - Dbus object path.
 *  @param[in] interface - Dbus interface.
 *  @param[in] method - Dbus method.
 */
void callDbusMethod(sdbusplus::bus_t& bus, const std::string& service,
                    const std::string& objPath, const std::string& interface,
                    const std::string& method);

} // namespace method_no_args

/** @brief Perform the low-level i2c bus write-read.
 *  @param[in] i2cBus - i2c bus device node name, such as /dev/i2c-2.
 *  @param[in] targetAddr - i2c device target address.
 *  @param[in] writeData - The data written to i2c device.
 *  @param[out] readBuf - Data read from the i2c device.
 */
ipmi::Cc i2cWriteRead(std::string i2cBus, const uint8_t targetAddr,
                      std::vector<uint8_t> writeData,
                      std::vector<uint8_t>& readBuf);
} // namespace ipmi
