#pragma once
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>

namespace phosphor
{
namespace button
{
enum class PowerEvent
{
    powerPressed,
    longPowerPressed,
    resetPressed,
    powerReleased,
    longPowerReleased,
    resetReleased
};
/**
 * @class Handler
 *
 * This class acts on the signals generated by the
 * xyz.openbmc_project.Chassis.Buttons code when
 * it detects button presses.
 *
 * There are 3 buttons supported - Power, ID, and Reset.
 * As not all systems may implement each button, this class will
 * check for that button on D-Bus before listening for its signals.
 */
class Handler
{
  public:
    Handler() = delete;
    ~Handler() = default;
    Handler(const Handler&) = delete;
    Handler& operator=(const Handler&) = delete;
    Handler(Handler&&) = delete;
    Handler& operator=(Handler&&) = delete;

    /**
     * @brief Constructor
     *
     * @param[in] bus - sdbusplus connection object
     */
    explicit Handler(sdbusplus::bus_t& bus);

  private:
    /**
     * @brief The handler for a power button press
     *
     * It will power on the system if it's currently off,
     * else it will soft power it off.
     *
     * @param[in] msg - sdbusplus message from signal
     */
    void powerReleased(sdbusplus::message_t& msg);

    /**
     * @brief The handler for a long power button press
     *
     * If the system is currently powered on, it will
     * perform an immediate power off.
     *
     * @param[in] msg - sdbusplus message from signal
     */
    void longPowerPressed(sdbusplus::message_t& msg);

    /**
     * @brief The handler for an ID button press
     *
     * Toggles the ID LED group
     *
     * @param[in] msg - sdbusplus message from signal
     */
    void idReleased(sdbusplus::message_t& msg);

    /**
     * @brief The handler for a reset button press
     *
     * Reboots the host if it is powered on.
     *
     * @param[in] msg - sdbusplus message from signal
     */
    void resetReleased(sdbusplus::message_t& msg);

    /**
     * @brief The handler for a OCP debug card host selector button press
     *
     * In multi host system increases host position by 1 up to max host
     * position.
     *
     * @param[in] msg - sdbusplus message from signal
     */

    void debugHostSelectorReleased(sdbusplus::message::message& msg);

    /**
     * @brief Checks if system is powered on
     *
     * @return true if powered on, false else
     */
    bool poweredOn(size_t hostNumber) const;

    /*
     * @return std::string - the D-Bus service name if found, else
     *                       an empty string
     */
    std::string getService(const std::string& path,
                           const std::string& interface) const;

    /**
     * @brief gets the valid host selector value in multi host
     * system
     *
     * @return size_t throws exception if host selector position is
     * invalid or not available.
     */

    size_t getHostSelectorValue();
    /**
     * @brief increases the host selector position property
     * by 1 upto max host selector position
     *
     * @return void
     */

    void increaseHostSelectorPosition();
    /**
     * @brief checks if the system has multi host
     * based on the host selector property availability
     *
     * @return bool returns true if multi host system
     * else returns false.
     */
    bool isMultiHost();
    /**
     * @brief trigger the power ctrl event based on the
     *  button press event type.
     *
     * @return void
     */
    void handlePowerEvent(PowerEvent powerEventType);

    /**
     * @brief sdbusplus connection object
     */
    sdbusplus::bus_t& bus;

    /**
     * @brief Matches on the power button released signal
     */
    std::unique_ptr<sdbusplus::bus::match_t> powerButtonReleased;

    /**
     * @brief Matches on the power button long press released signal
     */
    std::unique_ptr<sdbusplus::bus::match_t> powerButtonLongPressed;

    /**
     * @brief Matches on the ID button released signal
     */
    std::unique_ptr<sdbusplus::bus::match_t> idButtonReleased;

    /**
     * @brief Matches on the reset button released signal
     */
    std::unique_ptr<sdbusplus::bus::match_t> resetButtonReleased;

    /**
     * @brief Matches on the ocp debug host selector  button released signal
     */
    std::unique_ptr<sdbusplus::bus::match_t> debugHSButtonReleased;
};

} // namespace button
} // namespace phosphor
