#pragma once

#include "types.hpp"
#include "utils.hpp"

#include <sdbusplus/bus.hpp>

#include <memory>
#include <utility>

namespace phosphor
{
namespace inventory
{
namespace manager
{

class Manager;

/** @brief make_action
 *
 *  Adapt an action function object.
 *
 *  @param[in] action - The action being adapted.
 *  @returns - The adapted action.
 *
 *  @tparam T - The type of the action being adapted.
 */
template <typename T>
auto make_action(T&& action)
{
    return Action(std::forward<T>(action));
}

/** @brief make_filter
 *
 *  Adapt a filter function object.
 *
 *  @param[in] filter - The filter being adapted.
 *  @returns - The adapted filter.
 *
 *  @tparam T - The type of the filter being adapted.
 */
template <typename T>
auto make_filter(T&& filter)
{
    return Filter(std::forward<T>(filter));
}

/** @brief make_path_condition
 *
 *  Adapt a path_condition function object.
 *
 *  @param[in] filter - The functor being adapted.
 *  @returns - The adapted functor.
 *
 *  @tparam T - The type of the functor being adapted.
 */
template <typename T>
auto make_path_condition(T&& condition)
{
    return PathCondition(std::forward<T>(condition));
}

/** @brief make_get_property
 *
 *  Adapt a get_property function object.
 *
 *  @param[in] method - The functor being adapted.
 *  @returns - The adapted functor.
 *
 *  @tparam T - The return type of the function object.
 *  @tparam U - The type of the functor being adapted.
 */
template <typename T, typename U>
auto make_get_property(U&& method)
{
    return GetProperty<T>(std::forward<U>(method));
}

template <typename T, typename... Args>
auto callArrayWithStatus(T&& container, Args&&... args)
{
    for (auto f : container)
    {
        if (!f(std::forward<Args>(args)...))
        {
            return false;
        }
    }
    return true;
}

namespace functor
{

/** @brief Destroy objects action.  */
inline auto destroyObjects(std::vector<const char*>&& paths,
                           std::vector<PathCondition>&& conditions)
{
    return [=](auto& b, auto& m) {
        for (const auto& p : paths)
        {
            if (callArrayWithStatus(conditions, p, b, m))
            {
                m.destroyObjects({p});
            }
        }
    };
}

/** @brief Create objects action.  */
inline auto
    createObjects(std::map<sdbusplus::message::object_path, Object>&& objs)
{
    return [=](auto&, auto& m) { m.createObjects(objs); };
}

/** @brief Set a property action.
 *
 *  Invoke the requested method with a reference to the requested
 *  sdbusplus server binding interface as a parameter.
 *
 *  @tparam T - The sdbusplus server binding interface type.
 *  @tparam U - The type of the sdbusplus server binding member
 *      function that sets the property.
 *  @tparam V - The property value type.
 *
 *  @param[in] paths - The DBus paths on which the property should
 *      be set.
 *  @param[in] iface - The DBus interface hosting the property.
 *  @param[in] member - Pointer to sdbusplus server binding member.
 *  @param[in] value - The value the property should be set to.
 *
 *  @returns - A function object that sets the requested property
 *      to the requested value.
 */
template <typename T, typename U, typename V>
auto setProperty(std::vector<const char*>&& paths,
                 std::vector<PathCondition>&& conditions, const char* iface,
                 U&& member, V&& value)
{
    // The manager is the only parameter passed to actions.
    // Bind the path, interface, interface member function pointer,
    // and value to a lambda.  When it is called, forward the
    // path, interface and value on to the manager member function.
    return [paths, conditions = conditions, iface, member,
            value = std::forward<V>(value)](auto& b, auto& m) {
        for (auto p : paths)
        {
            if (callArrayWithStatus(conditions, p, b, m))
            {
                m.template invokeMethod<T>(p, iface, member, value);
            }
        }
    };
}

/** @brief Get a property.
 *
 *  Invoke the requested method with a reference to the requested
 *  sdbusplus server binding interface as a parameter.
 *
 *  @tparam T - The sdbusplus server binding interface type.
 *  @tparam U - The type of the sdbusplus server binding member
 *      function that sets the property.
 *
 *  @param[in] path - The DBus path to get the property from.
 *  @param[in] iface - The DBus interface hosting the property.
 *  @param[in] member - Pointer to sdbusplus server binding member.
 *  @param[in] prop - The property name to get the value from.
 *
 *  @returns - A function object that gets the requested property.
 */
template <typename T, typename U>
inline auto getProperty(const char* path, const char* iface, U&& member,
                        const char* prop)
{
    return [path, iface, member, prop](auto& mgr) {
        return mgr.template invokeMethod<T>(path, iface, member, prop);
    };
}

/** @struct PropertyChangedCondition
 *  @brief Match filter functor that tests a property value.
 *
 *  @tparam T - The type of the property being tested.
 *  @tparam U - The type of the condition checking functor.
 */
template <typename T, typename U>
struct PropertyChangedCondition
{
    PropertyChangedCondition() = delete;
    ~PropertyChangedCondition() = default;
    PropertyChangedCondition(const PropertyChangedCondition&) = default;
    PropertyChangedCondition&
        operator=(const PropertyChangedCondition&) = default;
    PropertyChangedCondition(PropertyChangedCondition&&) = default;
    PropertyChangedCondition& operator=(PropertyChangedCondition&&) = default;
    PropertyChangedCondition(const char* iface, const char* property,
                             U&& condition) :
        _iface(iface),
        _property(property), _condition(std::forward<U>(condition))
    {}

    /** @brief Test a property value.
     *
     * Extract the property from the PropertiesChanged
     * message and run the condition test.
     */
    bool operator()(sdbusplus::bus_t&, sdbusplus::message_t& msg,
                    Manager&) const
    {
        std::map<std::string, std::variant<T>> properties;
        const char* iface = nullptr;

        msg.read(iface);
        if (!iface || strcmp(iface, _iface))
        {
            return false;
        }

        msg.read(properties);
        auto it = properties.find(_property);
        if (it == properties.cend())
        {
            return false;
        }

        return _condition(std::forward<T>(std::get<T>(it->second)));
    }

  private:
    const char* _iface;
    const char* _property;
    U _condition;
};

/** @struct PropertyConditionBase
 *  @brief Match filter functor that tests a property value.
 *
 *  Base class for PropertyCondition - factored out code that
 *  doesn't need to be templated.
 */
struct PropertyConditionBase
{
    PropertyConditionBase() = delete;
    virtual ~PropertyConditionBase() = default;
    PropertyConditionBase(const PropertyConditionBase&) = default;
    PropertyConditionBase& operator=(const PropertyConditionBase&) = default;
    PropertyConditionBase(PropertyConditionBase&&) = default;
    PropertyConditionBase& operator=(PropertyConditionBase&&) = default;

    /** @brief Constructor
     *
     *  The service argument can be nullptr.  If something
     *  else is provided the function will call the the
     *  service directly.  If omitted, the function will
     *  look up the service in the ObjectMapper.
     *
     *  @param path - The path of the object containing
     *     the property to be tested.
     *  @param iface - The interface hosting the property
     *     to be tested.
     *  @param property - The property to be tested.
     *  @param service - The DBus service hosting the object.
     */
    PropertyConditionBase(const char* path, const char* iface,
                          const char* property, const char* service) :
        _path(path ? path : std::string()),
        _iface(iface), _property(property), _service(service)
    {}

    /** @brief Forward comparison to type specific implementation. */
    virtual bool eval(sdbusplus::message_t&) const = 0;

    /** @brief Forward comparison to type specific implementation. */
    virtual bool eval(Manager&) const = 0;

    /** @brief Test a property value.
     *
     * Make a DBus call and test the value of any property.
     */
    bool operator()(sdbusplus::bus_t&, sdbusplus::message_t&, Manager&) const;

    /** @brief Test a property value.
     *
     * Make a DBus call and test the value of any property.
     */
    bool operator()(const std::string&, sdbusplus::bus_t&, Manager&) const;

  private:
    std::string _path;
    std::string _iface;
    std::string _property;
    const char* _service;
};

/** @struct PropertyCondition
 *  @brief Match filter functor that tests a property value.
 *
 *  @tparam T - The type of the property being tested.
 *  @tparam U - The type of the condition checking functor.
 *  @tparam V - The getProperty functor return type.
 */
template <typename T, typename U, typename V>
struct PropertyCondition final : public PropertyConditionBase
{
    PropertyCondition() = delete;
    ~PropertyCondition() = default;
    PropertyCondition(const PropertyCondition&) = default;
    PropertyCondition& operator=(const PropertyCondition&) = default;
    PropertyCondition(PropertyCondition&&) = default;
    PropertyCondition& operator=(PropertyCondition&&) = default;

    /** @brief Constructor
     *
     *  The service & getProperty arguments can be nullptrs.
     *  If something else is provided the function will call the the
     *  service directly.  If omitted, the function will
     *  look up the service in the ObjectMapper.
     *  The getProperty function will be called to retrieve a property
     *  value when given and the property is hosted by inventory manager.
     *  When not given, the condition will default to return that the
     *  condition failed and will not be executed.
     *
     *  @param path - The path of the object containing
     *     the property to be tested.
     *  @param iface - The interface hosting the property
     *     to be tested.
     *  @param property - The property to be tested.
     *  @param condition - The test to run on the property.
     *  @param service - The DBus service hosting the object.
     *  @param getProperty - The function to get a property value
     *     for the condition.
     */
    PropertyCondition(const char* path, const char* iface, const char* property,
                      U&& condition, const char* service,
                      GetProperty<V>&& getProperty = nullptr) :
        PropertyConditionBase(path, iface, property, service),
        _condition(std::forward<decltype(condition)>(condition)),
        _getProperty(getProperty)
    {}

    /** @brief Test a property value.
     *
     * Make a DBus call and test the value of any property.
     */
    bool eval(sdbusplus::message_t& msg) const override
    {
        std::variant<T> value;
        msg.read(value);
        return _condition(std::forward<T>(std::get<T>(value)));
    }

    /** @brief Retrieve a property value from inventory and test it.
     *
     *  Get a property from the inventory manager and test the value.
     *  Default to fail the test where no function is given to get the
     *  property from the inventory manager.
     */
    bool eval(Manager& mgr) const override
    {
        if (_getProperty)
        {
            auto variant = _getProperty(mgr);
            auto value = std::get<T>(variant);
            return _condition(std::forward<T>(value));
        }
        return false;
    }

  private:
    U _condition;
    GetProperty<V> _getProperty;
};

/** @brief Implicit type deduction for constructing PropertyChangedCondition. */
template <typename T>
auto propertyChangedTo(const char* iface, const char* property, T&& val)
{
    auto condition = [val = std::forward<T>(val)](T&& arg) {
        return arg == val;
    };
    using U = decltype(condition);
    return PropertyChangedCondition<T, U>(iface, property,
                                          std::move(condition));
}

/** @brief Implicit type deduction for constructing PropertyCondition.  */
template <typename T, typename V = InterfaceVariantType>
auto propertyIs(const char* path, const char* iface, const char* property,
                T&& val, const char* service = nullptr,
                GetProperty<V>&& getProperty = nullptr)
{
    auto condition = [val = std::forward<T>(val)](T&& arg) {
        return arg == val;
    };
    using U = decltype(condition);
    return PropertyCondition<T, U, V>(path, iface, property,
                                      std::move(condition), service,
                                      std::move(getProperty));
}
} // namespace functor
} // namespace manager
} // namespace inventory
} // namespace phosphor

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
