#pragma once

#include "power_button_profile.hpp"

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

namespace phosphor
{
namespace button
{
enum class PowerEvent
{
    powerPressed,
    resetPressed,
    powerReleased,
    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 do power action according to the pressing duration.
     *
     * @param[in] msg - sdbusplus message from signal
     */
    void powerReleased(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_t& 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,
                          std::chrono::microseconds duration);

    /**
     * @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;

    /**
     * @brief The custom power handler profile object.
     */
    std::unique_ptr<PowerButtonProfile> powerButtonProfile;
};

} // namespace button
} // namespace phosphor
