#pragma once

#include "../manager.hpp"

#include <sdbusplus/message.hpp>

#include <algorithm>
#include <map>
#include <tuple>
#include <vector>

namespace phosphor::fan::control::json::trigger::signal
{

using namespace sdbusplus::message;

struct Handlers
{
  public:
    /**
     * @brief Processes a properties changed signal and updates the property's
     * value in the manager's object cache
     *
     * @param[in] msg - The sdbusplus signal message
     * @param[in] obj - Object data associated with the signal
     * @param[in] mgr - Manager that stores the object cache
     */
    static bool propertiesChanged(message& msg, const SignalObject& obj,
                                  Manager& mgr)
    {
        std::string intf;
        msg.read(intf);
        if (intf != std::get<Intf>(obj))
        {
            // Interface name does not match object's interface
            return false;
        }

        std::map<std::string, PropertyVariantType> props;
        msg.read(props);
        auto itProp = props.find(std::get<Prop>(obj));
        if (itProp == props.cend())
        {
            // Object's property not in dictionary of properties changed
            return false;
        }

        mgr.setProperty(std::get<Path>(obj), std::get<Intf>(obj),
                        std::get<Prop>(obj), itProp->second);
        return true;
    }

    /**
     * @brief Processes an interfaces added signal and adds the interface
     * (including property & property value) to the manager's object cache
     *
     * @param[in] msg - The sdbusplus signal message
     * @param[in] obj - Object data associated with the signal
     * @param[in] mgr - Manager that stores the object cache
     */
    static bool interfacesAdded(message& msg, const SignalObject& obj,
                                Manager& mgr)
    {
        sdbusplus::message::object_path op;
        msg.read(op);
        if (static_cast<const std::string&>(op) != std::get<Path>(obj))
        {
            // Path name does not match object's path
            return false;
        }

        std::map<std::string, std::map<std::string, PropertyVariantType>>
            intfProps;
        msg.read(intfProps);
        auto itIntf = intfProps.find(std::get<Intf>(obj));
        if (itIntf == intfProps.cend())
        {
            // Object's interface not in dictionary of interfaces added
            return false;
        }

        auto itProp = itIntf->second.find(std::get<Prop>(obj));
        if (itProp == itIntf->second.cend())
        {
            // Object's property not in dictionary of properties of interface
            return false;
        }

        mgr.setProperty(std::get<Path>(obj), std::get<Intf>(obj),
                        std::get<Prop>(obj), itProp->second);
        return true;
    }

    /**
     * @brief Processes an interfaces removed signal and removes the interface
     * (including its properties) from the object cache on the manager
     *
     * @param[in] msg - The sdbusplus signal message
     * @param[in] obj - Object data associated with the signal
     * @param[in] mgr - Manager that stores the object cache
     */
    static bool interfacesRemoved(message& msg, const SignalObject& obj,
                                  Manager& mgr)
    {
        sdbusplus::message::object_path op;
        msg.read(op);
        if (static_cast<const std::string&>(op) != std::get<Path>(obj))
        {
            // Path name does not match object's path
            return false;
        }

        std::vector<std::string> intfs;
        msg.read(intfs);
        auto itIntf =
            std::find(intfs.begin(), intfs.end(), std::get<Intf>(obj));
        if (itIntf == intfs.cend())
        {
            // Object's interface not in list of interfaces removed
            return false;
        }

        mgr.removeInterface(std::get<Path>(obj), std::get<Intf>(obj));
        return true;
    }

    /**
     * @brief Processes a name owner changed signal and updates the service's
     * owner state for all objects/interfaces associated in the cache
     *
     * @param[in] msg - The sdbusplus signal message
     * @param[in] mgr - Manager that stores the service's owner state
     */
    static bool nameOwnerChanged(message& msg, const SignalObject&,
                                 Manager& mgr)
    {
        bool hasOwner = false;

        std::string serv;
        msg.read(serv);

        std::string oldOwner;
        msg.read(oldOwner);

        std::string newOwner;
        msg.read(newOwner);
        if (!newOwner.empty())
        {
            hasOwner = true;
        }

        mgr.setOwner(serv, hasOwner);
        return true;
    }

    /**
     * @brief Processes a dbus member signal, there is nothing associated or
     * any cache to update when this signal is received
     */
    static bool member(message&, const SignalObject&, Manager&)
    {
        return true;
    }
};

} // namespace phosphor::fan::control::json::trigger::signal
