#pragma once

#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <functional>
#include <xyz/openbmc_project/Control/Host/server.hpp>
#include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>
#include "timer.hpp"
#include "config.h"
namespace phosphor
{
namespace ipmi
{

namespace Base = sdbusplus::xyz::openbmc_project::Ipmi::Internal::server;
using namespace sdbusplus::xyz::openbmc_project::Control::server;

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

/** @class SoftPowerOff
 *  @brief Responsible for coordinating Host SoftPowerOff operation
 */
class SoftPowerOff : public sdbusplus::server::object::object<
                     Base::SoftPowerOff>
{
    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::bus& bus,
                     sd_event* event,
                     const char* objPath) :
            sdbusplus::server::object::object<
                Base::SoftPowerOff>(bus, objPath, false),
                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::bus& bus;

        /** @brief Reference to Timer object */
        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::message& msg);

};
} // namespace ipmi
} // namespace phosphor
