#pragma once

#include <functional>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <org/open_power/OCC/Status/server.hpp>
#include <org/open_power/Control/Host/server.hpp>
#include "occ_events.hpp"
#include "occ_device.hpp"
#include "i2c_occ.hpp"

namespace open_power
{
namespace occ
{

class Manager;
namespace Base = sdbusplus::org::open_power::OCC::server;
using Interface = sdbusplus::server::object::object<Base::Status>;

// IPMID's host control application
namespace Control = sdbusplus::org::open_power::Control::server;

// For waiting on signals
namespace sdbusRule = sdbusplus::bus::match::rules;

// OCC status instance. Ex. for "occ0", the instance is 0
using instanceID = int;

// IPMI sensor ID for a given OCC instance
using sensorID = uint8_t;

/** @class Status
 *  @brief Implementation of OCC Active Status
 */
class Status : public Interface
{
    public:
        Status() = delete;
        ~Status() = default;
        Status(const Status&) = delete;
        Status& operator=(const Status&) = delete;
        Status(Status&&) = default;
        Status& operator=(Status&&) = default;

        /** @brief Constructs the Status object and
         *         the underlying device object
         *
         *  @param[in] bus      - DBus bus to attach to
         *  @param[in] event    - sd_event unique pointer reference
         *  @param[in] path     - DBus object path
         *  @param[in] manager  - OCC manager instance
         *  @param[in] callBack - Callback handler to invoke during
         *                        property change
         */
        Status(sdbusplus::bus::bus& bus,
               EventPtr& event,
               const char* path,
               const Manager& manager,
               std::function<void(bool)> callBack = nullptr)
            : Interface(bus, path, true),
              bus(bus),
              path(path),
              callBack(callBack),
              instance(((this->path.back() - '0'))),
              device(event,
#ifdef I2C_OCC
                     i2c_occ::getI2cDeviceName(path),
#else
                     name + std::to_string(instance + 1),
#endif
                     manager,
                     std::bind(&Status::deviceErrorHandler, this)),
              hostControlSignal(
                     bus,
                     sdbusRule::type::signal() +
                     sdbusRule::member("CommandComplete") +
                     sdbusRule::path("/org/open_power/control/host0") +
                     sdbusRule::interface("org.open_power.Control.Host") +
                     sdbusRule::argN(0, Control::convertForMessage(
                             Control::Host::Command::OCCReset)),
                     std::bind(std::mem_fn(&Status::hostControlEvent),
                            this, std::placeholders::_1))
        {
            // Check to see if we have OCC already bound.  If so, just set it
            if (device.bound())
            {
                this->occActive(true);
            }

            // Announce that we are ready
            this->emit_object_added();
        }

        /** @brief Since we are overriding the setter-occActive but not the
         *         getter-occActive, we need to have this using in order to
         *         allow passthrough usage of the getter-occActive
         */
        using Base::Status::occActive;

        /** @brief SET OccActive to True or False
         *
         *  @param[in] value - Intended value
         *
         *  @return          - Updated value of the property
         */
        bool occActive(bool value) override;

        /** @brief Starts OCC error detection */
        inline void addErrorWatch()
        {
            return device.addErrorWatch();
        }

        /** @brief Stops OCC error detection */
        inline void removeErrorWatch()
        {
            return device.removeErrorWatch();
        }

    private:

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

        /** @brief OCC dbus object path */
        std::string path;

        /** @brief Callback handler to be invoked during property change.
         *         This is a handler in Manager class
         */
        std::function<void(bool)> callBack;

        /** @brief occ name prefix */
        std::string name = OCC_NAME;

        /** @brief OCC instance number. Ex, 0,1, etc */
        int instance;

        /** @brief OCC instance to Sensor ID mapping */
        static const std::map<instanceID, sensorID> sensorMap;

        /** @brief OCC device object to do bind and unbind */
        Device device;

        /** @brief Subscribe to host control signal
         *
         *  Once the OCC reset is requested, BMC sends that message to host.
         *  If the host does not ack the message, then there would be a timeout
         *  and we need to catch that to log an error
         **/
        sdbusplus::bus::match_t hostControlSignal;

        /** @brief Callback handler when device errors are detected */
        void deviceErrorHandler();

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

        /** @brief Sends a message to host control command handler to reset OCC
         */
        void resetOCC();
};

} // namespace occ
} // namespace open_power
