#pragma once

#include "config.h"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <sdbusplus/timer.hpp>
#include <xyz/openbmc_project/Control/Host/server.hpp>
#include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>

#include <functional>
namespace phosphor
{
namespace ipmi
{

namespace Base = sdbusplus::server::xyz::openbmc_project::ipmi::internal;
using namespace sdbusplus::server::xyz::openbmc_project::control;

namespace sdbusRule = sdbusplus::bus::match::rules;

namespace
{
using SoftPowerOffInherit = sdbusplus::server::object_t<Base::SoftPowerOff>;
}

/** @class SoftPowerOff
 *  @brief Responsible for coordinating Host SoftPowerOff operation
 */
class SoftPowerOff : public SoftPowerOffInherit
{
  public:
    /** @brief Constructs SoftPowerOff object.
     *
     *  @param[in] bus       - system dbus handler
     *  @param[in] event     - sd_event handler
     *  @param[in] objPath   - The Dbus path hosting SoftPowerOff function
     */
    SoftPowerOff(sdbusplus::bus_t& bus, sd_event* event, const char* objPath) :
        SoftPowerOffInherit(bus, objPath,
                            SoftPowerOffInherit::action::defer_emit),
        bus(bus), timer(event),
        hostControlSignal(
            bus,
            sdbusRule::type::signal() + sdbusRule::member("CommandComplete") +
                sdbusRule::path("/xyz/openbmc_project/control/host0") +
                sdbusRule::interface(CONTROL_HOST_BUSNAME) +
                sdbusRule::argN(0, convertForMessage(Host::Command::SoftOff)),
            std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), this,
                      std::placeholders::_1))
    {
        // Need to announce since we may get the response
        // very quickly on host shutdown command
        emit_object_added();

        // The whole purpose of this application is to send a host shutdown
        // command and watch for the soft power off to go through. We need
        // the interface added signal emitted before we send the shutdown
        // command just to attend to lightning fast response from host
        sendHostShutDownCmd();
    }

    /** @brief Tells if the objective of this application is completed */
    inline auto isCompleted()
    {
        return completed;
    }

    /** @brief Tells if the referenced timer is expired or not */
    inline auto isTimerExpired()
    {
        return timer.isExpired();
    }

    /** @brief overloaded property setter function
     *
     *  @param[in] value - One of SoftOffReceived / HostShutdown
     *
     *  @return Success or exception thrown
     */
    HostResponse responseReceived(HostResponse value) override;

    /** @brief Using the base class's getter method */
    using Base::SoftPowerOff::responseReceived;

    /** @brief Calls to start a timer
     *
     *  @param[in] usec - Time in microseconds
     *
     *  @return Success or exception thrown
     */
    int startTimer(const std::chrono::microseconds& usec);

  private:
    // Need this to send SMS_ATTN
    // TODO : Switch over to using mapper service in a different patch
    static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi";
    static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1";
    static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi";

    /* @brief sdbusplus handle */
    sdbusplus::bus_t& bus;

    /** @brief Reference to Timer object */
    sdbusplus::Timer timer;

    /** @brief Marks the end of life of this application.
     *
     *  This is set to true if host gives appropriate responses
     *  for the sequence of commands.
     */
    bool completed = false;

    /** @brief Subscribe to host control signals
     *
     *  Protocol is to send the host power off request to the host
     *  control interface and then wait for a signal indicating pass/fail
     **/
    sdbusplus::bus::match_t hostControlSignal;

    /** @brief Sends host control command to tell host to shut down
     *
     *  After sending the command, wait for a signal indicating the status
     *  of the command.
     *
     *  After receiving the initial response, start a timer for 30 minutes
     *  to let host do a clean shutdown of partitions. When the response is
     *  received from the host, it indicates that BMC can do a power off.
     *  If BMC fails to get any response, then a hard power off would
     *  be forced.
     *
     *  @return - Does not return anything. Error will result in exception
     *            being thrown
     */
    void sendHostShutDownCmd();

    /** @brief Callback function on host control signals
     *
     * @param[in]  msg       - Data associated with subscribed signal
     *
     */
    void hostControlEvent(sdbusplus::message_t& msg);
};
} // namespace ipmi
} // namespace phosphor
