#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
