#pragma once

#include "common/instance_id.hpp"
#include "common/types.hpp"
#include "common/utils.hpp"
#include "requester/handler.hpp"

#include <phosphor-logging/lg2.hpp>

#include <string>
#include <utility>
#include <vector>

PHOSPHOR_LOG2_USING;

namespace pldm
{

namespace host_effecters
{

using DbusChgHostEffecterProps =
    std::map<dbus::Property, pldm::utils::PropertyValue>;

/** @struct State
 *  Contains the state set id and the possible states for
 *  an effecter
 */
struct PossibleState
{
    uint16_t stateSetId;         //!< State set id
    std::vector<uint8_t> states; //!< Possible states
};

/** @struct DBusEffecterMapping
 *  Contains the D-Bus information for an effecter
 */
struct DBusEffecterMapping
{
    pldm::utils::DBusMapping dbusMap;
    std::vector<pldm::utils::PropertyValue>
        propertyValues;  //!< D-Bus property values
    PossibleState state; //!< Corresponding effecter states
};

/** @struct EffecterInfo
 *  Contains the effecter information as a whole
 */
struct EffecterInfo
{
    uint8_t mctpEid;         //!< Host mctp eid
    uint16_t containerId;    //!< Container Id for host effecter
    uint16_t entityType;     //!< Entity type for the host effecter
    uint16_t entityInstance; //!< Entity instance for the host effecter
    uint8_t compEffecterCnt; //!< Composite effecter count
    std::vector<DBusEffecterMapping>
        dbusInfo;            //!< D-Bus information for the effecter id
};

/** @class HostEffecterParser
 *
 *  @brief This class parses the Host Effecter json file and monitors for the
 *         D-Bus changes for the effecters. Upon change, calls the corresponding
 *         setStateEffecterStates on the host
 */
class HostEffecterParser
{
  public:
    HostEffecterParser() = delete;
    HostEffecterParser(const HostEffecterParser&) = delete;
    HostEffecterParser& operator=(const HostEffecterParser&) = delete;
    HostEffecterParser(HostEffecterParser&&) = delete;
    HostEffecterParser& operator=(HostEffecterParser&&) = delete;
    virtual ~HostEffecterParser() = default;

    /** @brief Constructor to create a HostEffecterParser object.
     *  @param[in] instanceIdDb - PLDM InstanceIdDb object pointer
     *  @param[in] fd - socket fd to communicate to host
     *  @param[in] repo -  PLDM PDR repository
     *  @param[in] dbusHandler - D-bus Handler
     *  @param[in] jsonPath - path for the json file
     *  @param[in] handler - PLDM request handler
     */
    explicit HostEffecterParser(
        pldm::InstanceIdDb* instanceIdDb, int fd, const pldm_pdr* repo,
        pldm::utils::DBusHandler* const dbusHandler,
        const std::string& jsonPath,
        pldm::requester::Handler<pldm::requester::Request>* handler) :
        instanceIdDb(instanceIdDb),
        sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), handler(handler)
    {
        try
        {
            parseEffecterJson(jsonPath);
        }
        catch (const std::exception& e)
        {
            error(
                "The json file does not exist or malformed, ERROR={ERR_EXCEP}",
                "ERR_EXCEP", e.what());
        }
    }

    /* @brief Parses the host effecter json
     *
     * @param[in] jsonPath - path for the json file
     */
    void parseEffecterJson(const std::string& jsonPath);

    /* @brief Method to take action when the subscribed D-Bus property is
     *        changed
     * @param[in] chProperties - list of properties which have changed
     * @param[in] effecterInfoIndex - index of effecterInfo pointer in
     *                                hostEffecterInfo
     * @param[in] dbusInfoIndex - index on dbusInfo pointer in each effecterInfo
     * @param[in] effecterId - host effecter id
     * @return - none
     */
    void processHostEffecterChangeNotification(
        const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
        size_t dbusInfoIndex, uint16_t effecterId);

    /* @brief Populate the property values in each dbusInfo from the json
     *
     * @param[in] dBusValues - json values
     * @param[out] propertyValues - dbusInfo property values
     * @param[in] propertyType - type of the D-Bus property
     * @return - none
     */
    void populatePropVals(
        const pldm::utils::Json& dBusValues,
        std::vector<pldm::utils::PropertyValue>& propertyValues,
        const std::string& propertyType);

    /* @brief Set a host state effecter
     *
     * @param[in] effecterInfoIndex - index of effecterInfo pointer in
     *                                hostEffecterInfo
     * @param[in] stateField - vector of state fields equal to composite
     *                         effecter count in number
     * @param[in] effecterId - host effecter id
     * @return - PLDM status code
     */
    virtual int
        setHostStateEffecter(size_t effecterInfoIndex,
                             std::vector<set_effecter_state_field>& stateField,
                             uint16_t effecterId);

    /* @brief Fetches the new state value and the index in stateField set which
     *        needs to be set with the new value in the setStateEffecter call
     * @param[in] effecterInfoIndex - index of effecterInfo in hostEffecterInfo
     * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
     * @param[in] propertyValue - the changed D-Bus property value
     * @return - the new state value
     */
    uint8_t findNewStateValue(size_t effecterInfoIndex, size_t dbusInfoIndex,
                              const pldm::utils::PropertyValue& propertyValue);

    /* @brief Subscribes for D-Bus property change signal on the specified
     * object
     *
     * @param[in] objectPath - D-Bus object path to look for
     * @param[in] interface - D-Bus interface
     * @param[in] effecterInfoIndex - index of effecterInfo pointer in
     *                                hostEffecterInfo
     * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
     * @param[in] effecterId - host effecter id
     */
    virtual void createHostEffecterMatch(const std::string& objectPath,
                                         const std::string& interface,
                                         size_t effecterInfoIndex,
                                         size_t dbusInfoIndex,
                                         uint16_t effecterId);

  protected:
    pldm::InstanceIdDb* instanceIdDb; //!< Reference to the InstanceIdDb object
                                      //!< to obtain instance id
    int sockFd;                       //!< Socket fd to send message to host
    const pldm_pdr* pdrRepo;          //!< Reference to PDR repo
    std::vector<EffecterInfo> hostEffecterInfo; //!< Parsed effecter information
    std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
        effecterInfoMatch; //!< vector to catch the D-Bus property change
                           //!< signals for the effecters
    const pldm::utils::DBusHandler* dbusHandler; //!< D-bus Handler
    /** @brief PLDM request handler */
    pldm::requester::Handler<pldm::requester::Request>* handler;
};

} // namespace host_effecters
} // namespace pldm
