#pragma once

#include "libpldmresponder/platform.hpp"

#include <libpldm/base.h>

#include <sdeventplus/source/event.hpp>

#include <cstdint>
#include <vector>

using namespace pldm::responder;

namespace pldm
{
namespace responder
{
namespace base
{

#define PLDM_TYPES_MAX 63
#define PLDM_MIN_PART_SIZE 256
// TODO: We can make the part size configurable for different platforms
#define PLDM_RESPONDER_PART_SIZE 4096

class Handler : public CmdHandler
{
  public:
    Handler(sdeventplus::Event& event) : event(event)
    {
        handlers.emplace(
            PLDM_GET_PLDM_TYPES,
            [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
                return this->getPLDMTypes(request, payloadLength);
            });
        handlers.emplace(
            PLDM_GET_PLDM_COMMANDS,
            [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
                return this->getPLDMCommands(request, payloadLength);
            });
        handlers.emplace(
            PLDM_GET_PLDM_VERSION,
            [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
                return this->getPLDMVersion(request, payloadLength);
            });
        handlers.emplace(
            PLDM_GET_TID,
            [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
                return this->getTID(request, payloadLength);
            });
        handlers.emplace(PLDM_NEGOTIATE_TRANSFER_PARAMETERS,
                         [this](pldm_tid_t tid, const pldm_msg* request,
                                size_t payloadLength) {
                             return this->getNegotiateTransferParam(
                                 tid, request, payloadLength);
                         });
        handlers.emplace(PLDM_MULTIPART_RECEIVE, [this](pldm_tid_t tid,
                                                        const pldm_msg* request,
                                                        size_t payloadLength) {
            return this->getMultipartReceive(tid, request, payloadLength);
        });
    }

    /** @brief Handler for getPLDMTypes
     *
     *  @param[in] request - Request message payload
     *  @param[in] payload_length - Request message payload length
     *  @param[return] Response - PLDM Response message
     */
    Response getPLDMTypes(const pldm_msg* request, size_t payloadLength);

    /** @brief Handler for getPLDMCommands
     *
     *  @param[in] request - Request message payload
     *  @param[in] payload_length - Request message payload length
     *  @param[return] Response - PLDM Response message
     */
    Response getPLDMCommands(const pldm_msg* request, size_t payloadLength);

    /** @brief Handler for getPLDMCommands
     *
     *  @param[in] request - Request message payload
     *  @param[in] payload_length - Request message payload length
     *  @param[return] Response - PLDM Response message
     */
    Response getPLDMVersion(const pldm_msg* request, size_t payloadLength);

    /** @brief _processSetEventReceiver does the actual work that needs
     *  to be carried out for setEventReceiver command. This is deferred
     *  after sending response for getTID command to the host
     *
     *  @param[in] source - sdeventplus event source
     */
    void _processSetEventReceiver(sdeventplus::source::EventBase& source);

    /** @brief Handler for getTID
     *
     *  @param[in] request - Request message payload
     *  @param[in] payload_length - Request message payload length
     *  @param[return] Response - PLDM Response message
     */
    Response getTID(const pldm_msg* request, size_t payloadLength);

    /** @brief Handler for negotiate transfer parameters
     *
     * This will save the negotiated part size based on the TID
     *
     *  @param[in] tid - TID of the requester
     *  @param[in] request - Request message payload
     *  @param[in] payload_length - Request message payload length
     *  @param[return] Response - PLDM Response message
     */
    Response getNegotiateTransferParam(pldm_tid_t tid, const pldm_msg* request,
                                       size_t payloadLength);

    /** @brief Handler for MultipartReceive requests
     *
     * This will call the corresponding MultipartReceive handler based on the
     * PLDM type in the request.
     *
     *  @param[in] tid - TID of the requester
     *  @param[in] request - Request message payload
     *  @param[in] payloadLength - Request message payload length
     *  @param[return] Response - PLDM Response message
     */
    Response getMultipartReceive(pldm_tid_t tid, const pldm_msg* request,
                                 size_t payloadLength);

    /* @brief Method to set the oem platform handler in base handler class
     *
     * @param[in] handler - oem platform handler
     */
    inline void setOemPlatformHandler(
        pldm::responder::oem_platform::Handler* handler)
    {
        oemPlatformHandler = handler;
    }

    /* @brief Returns the negotiated part size for a given TID and PLDM type.
     *
     * If no negotiation has occurred for the given TID and type, it returns a
     * default minimum part size.
     *
     * @param[in] tid - The Terminus ID.
     * @param[in] pldmType - The PLDM type.
     * @return The negotiated part size.
     */
    uint16_t getNegotiatedPartSize(pldm_tid_t tid, uint8_t pldmType);

    /** @brief Registers a handler for MultipartReceive commands for a specific
     * PLDM type.
     *
     *  @param[in] pldmType - The PLDM type for which the handler is registered.
     *  @param[in] handler - A pointer to the CmdHandler instance that will
     *                       handle the MultipartReceive command for the given
     *                       PLDM type.
     */
    void registerMultipartReceiveHandler(uint8_t pldmType, CmdHandler* handler);

  private:
    /** @brief reference of main event loop of pldmd, primarily used to schedule
     *  work
     */
    sdeventplus::Event& event;

    /** @brief OEM platform handler */
    pldm::responder::oem_platform::Handler* oemPlatformHandler = nullptr;

    /** @brief sdeventplus event source */
    std::unique_ptr<sdeventplus::source::Defer> survEvent;

    /** Negotiated multi part size of each possible PLDM type for different
     * devices. */
    std::map<pldm_tid_t, std::map<uint8_t, uint16_t>> negotiatedPartSizes;

    /** Store handlers to be called for  multipart receive commands*/
    std::map<uint8_t, CmdHandler*> multipartReceivehandlers;
};

} // namespace base
} // namespace responder
} // namespace pldm
