#pragma once

#include "types.hpp"

#include <experimental/any>
#include <sdbusplus/bus.hpp>
#include <set>
#include <string>
#include <vector>

namespace utils
{

class UtilsInterface;

using AssociationList = phosphor::software::updater::AssociationList;
// Due to a libstdc++ bug, we got compile error using std::any with gmock.
// A temporary workaround is to use std::experimental::any.
// See details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415
using std::experimental::any;
using std::experimental::any_cast;

/**
 * @brief Get the implementation of UtilsInterface
 */
const UtilsInterface& getUtils();

/**
 * @brief Get PSU inventory object path from DBus
 */
std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus);

/** @brief Get service name from object path and interface
 *
 * @param[in] bus          - The Dbus bus object
 * @param[in] path         - The Dbus object path
 * @param[in] interface    - The Dbus interface
 *
 * @return The name of the service
 */
std::string getService(sdbusplus::bus::bus& bus, const char* path,
                       const char* interface);

/** @brief Get all the service names from object path and interface
 *
 * @param[in] bus          - The Dbus bus object
 * @param[in] path         - The Dbus object path
 * @param[in] interface    - The Dbus interface
 *
 * @return The name of the services
 */
std::vector<std::string> getServices(sdbusplus::bus::bus& bus, const char* path,
                                     const char* interface);

/** @brief The template function to get property from the requested dbus path
 *
 * @param[in] bus          - The Dbus bus object
 * @param[in] service      - The Dbus service name
 * @param[in] path         - The Dbus object path
 * @param[in] interface    - The Dbus interface
 * @param[in] propertyName - The property name to get
 *
 * @return The value of the property
 */
template <typename T>
T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
              const char* interface, const char* propertyName);

/**
 * @brief Calculate the version id from the version string.
 *
 * @details The version id is a unique 8 hexadecimal digit id
 *          calculated from the version string.
 *
 * @param[in] version - The image version string (e.g. v1.99.10-19).
 *
 * @return The id.
 */
std::string getVersionId(const std::string& version);

/** @brief Get version of PSU specified by the inventory path
 *
 * @param[in] inventoryPath - The PSU inventory object path
 *
 * @return The version string, or empry string if it fails to get the version
 */
std::string getVersion(const std::string& inventoryPath);

/** @brief Get latest version from the PSU versions
 *
 * @param[in] versions - The list of the versions
 *
 * @return The latest version string
 */
std::string getLatestVersion(const std::set<std::string>& versions);

/** @brief Check if the PSU is associated
 *
 * @param[in] psuInventoryPath - The PSU inventory path
 * @param[in] assocs - The list of associations
 *
 * @return true if the psu is in the association list
 */
bool isAssociated(const std::string& psuInventoryPath,
                  const AssociationList& assocs);

/**
 * @brief The interface for utils
 */
class UtilsInterface
{
  public:
    // For now the code needs to get property for Present and Version
    using PropertyType = sdbusplus::message::variant<std::string, bool>;

    virtual ~UtilsInterface() = default;

    virtual std::vector<std::string>
        getPSUInventoryPath(sdbusplus::bus::bus& bus) const = 0;

    virtual std::string getService(sdbusplus::bus::bus& bus, const char* path,
                                   const char* interface) const = 0;

    virtual std::vector<std::string>
        getServices(sdbusplus::bus::bus& bus, const char* path,
                    const char* interface) const = 0;

    virtual std::string getVersionId(const std::string& version) const = 0;

    virtual std::string getVersion(const std::string& inventoryPath) const = 0;

    virtual std::string
        getLatestVersion(const std::set<std::string>& versions) const = 0;

    virtual bool isAssociated(const std::string& psuInventoryPath,
                              const AssociationList& assocs) const = 0;

    virtual any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
                                const char* path, const char* interface,
                                const char* propertyName) const = 0;

    template <typename T>
    T getProperty(sdbusplus::bus::bus& bus, const char* service,
                  const char* path, const char* interface,
                  const char* propertyName) const
    {
        any result =
            getPropertyImpl(bus, service, path, interface, propertyName);
        auto value = any_cast<PropertyType>(result);
        return sdbusplus::message::variant_ns::get<T>(value);
    }
};

class Utils : public UtilsInterface
{
  public:
    std::vector<std::string>
        getPSUInventoryPath(sdbusplus::bus::bus& bus) const override;

    std::string getService(sdbusplus::bus::bus& bus, const char* path,
                           const char* interface) const override;

    std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
                                         const char* path,
                                         const char* interface) const override;

    std::string getVersionId(const std::string& version) const override;

    std::string getVersion(const std::string& inventoryPath) const override;

    std::string
        getLatestVersion(const std::set<std::string>& versions) const override;

    bool isAssociated(const std::string& psuInventoryPath,
                      const AssociationList& assocs) const override;

    any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
                        const char* path, const char* interface,
                        const char* propertyName) const override;
};

inline std::string getService(sdbusplus::bus::bus& bus, const char* path,
                              const char* interface)
{
    return getUtils().getService(bus, path, interface);
}

inline std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
                                            const char* path,
                                            const char* interface)
{
    return getUtils().getServices(bus, path, interface);
}

inline std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus)
{
    return getUtils().getPSUInventoryPath(bus);
}

inline std::string getVersionId(const std::string& version)
{
    return getUtils().getVersionId(version);
}

inline std::string getVersion(const std::string& inventoryPath)
{
    return getUtils().getVersion(inventoryPath);
}

inline std::string getLatestVersion(const std::set<std::string>& versions)
{
    return getUtils().getLatestVersion(versions);
}

inline bool isAssociated(const std::string& psuInventoryPath,
                         const AssociationList& assocs)
{
    return getUtils().isAssociated(psuInventoryPath, assocs);
}

template <typename T>
T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
              const char* interface, const char* propertyName)
{
    return getUtils().getProperty<T>(bus, service, path, interface,
                                     propertyName);
}

} // namespace utils
