#pragma once

#include "common/flight_recorder.hpp"
#include "common/transport.hpp"
#include "common/types.hpp"
#include "common/utils.hpp"

#include <libpldm/base.h>
#include <sys/socket.h>

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/timer.hpp>
#include <sdeventplus/event.hpp>

#include <chrono>
#include <functional>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace requester
{
/** @class RequestRetryTimer
 *
 *  The abstract base class for implementing the PLDM request retry logic. This
 *  class handles number of times the PLDM request needs to be retried if the
 *  response is not received and the time to wait between each retry. It
 *  provides APIs to start and stop the request flow.
 */
class RequestRetryTimer
{
  public:
    RequestRetryTimer() = delete;
    RequestRetryTimer(const RequestRetryTimer&) = delete;
    RequestRetryTimer(RequestRetryTimer&&) = delete;
    RequestRetryTimer& operator=(const RequestRetryTimer&) = delete;
    RequestRetryTimer& operator=(RequestRetryTimer&&) = delete;
    virtual ~RequestRetryTimer() = default;

    /** @brief Constructor
     *
     *  @param[in] event - reference to PLDM daemon's main event loop
     *  @param[in] numRetries - number of request retries
     *  @param[in] timeout - time to wait between each retry in milliseconds
     */
    explicit RequestRetryTimer(sdeventplus::Event& event, uint8_t numRetries,
                               std::chrono::milliseconds timeout) :

        event(event), numRetries(numRetries), timeout(timeout),
        timer(event.get(), [this] { this->callback(); })
    {}

    /** @brief Starts the request flow and arms the timer for request retries
     *
     *  @return return PLDM_SUCCESS on success and PLDM_ERROR otherwise
     */
    int start()
    {
        auto rc = send();
        if (rc)
        {
            return rc;
        }

        try
        {
            if (numRetries)
            {
                timer.start(duration_cast<std::chrono::microseconds>(timeout),
                            true);
            }
        }
        catch (const std::runtime_error& e)
        {
            error("Failed to start the request timer, error - {ERROR}", "ERROR",
                  e);
            return PLDM_ERROR;
        }

        return PLDM_SUCCESS;
    }

    /** @brief Stops the timer and no further request retries happen */
    void stop()
    {
        auto rc = timer.stop();
        if (rc)
        {
            error("Failed to stop the request timer, response code '{RC}'",
                  "RC", rc);
        }
    }

  protected:
    sdeventplus::Event& event; //!< reference to PLDM daemon's main event loop
    uint8_t numRetries;        //!< number of request retries
    std::chrono::milliseconds
        timeout;            //!< time to wait between each retry in milliseconds
    sdbusplus::Timer timer; //!< manages starting timers and handling timeouts

    /** @brief Sends the PLDM request message
     *
     *  @return return PLDM_SUCCESS on success and PLDM_ERROR otherwise
     */
    virtual int send() const = 0;

    /** @brief Callback function invoked when the timeout happens */
    void callback()
    {
        if (numRetries--)
        {
            send();
        }
        else
        {
            stop();
        }
    }
};

/** @class Request
 *
 *  The concrete implementation of RequestIntf. This class implements the send()
 *  to send the PLDM request message over MCTP socket.
 *  This class encapsulates the PLDM request message, the number of times the
 *  request needs to retried if the response is not received and the amount of
 *  time to wait between each retry. It provides APIs to start and stop the
 *  request flow.
 */
class Request final : public RequestRetryTimer
{
  public:
    Request() = delete;
    Request(const Request&) = delete;
    Request(Request&&) = delete;
    Request& operator=(const Request&) = delete;
    Request& operator=(Request&&) = delete;
    ~Request() override = default;

    /** @brief Constructor
     *
     *  @param[in] pldm_transport - PLDM transport object
     *  @param[in] eid - endpoint ID of the remote MCTP endpoint
     *  @param[in] currrentSendbuffSize - the current send buffer size
     *  @param[in] event - reference to PLDM daemon's main event loop
     *  @param[in] requestMsg - PLDM request message
     *  @param[in] numRetries - number of request retries
     *  @param[in] timeout - time to wait between each retry in milliseconds
     *  @param[in] verbose - verbose tracing flag
     */
    explicit Request(PldmTransport* pldmTransport, mctp_eid_t eid,
                     sdeventplus::Event& event, pldm::Request&& requestMsg,
                     uint8_t numRetries, std::chrono::milliseconds timeout,
                     bool verbose) :
        RequestRetryTimer(event, numRetries, timeout),
        pldmTransport(pldmTransport), eid(eid),
        requestMsg(std::move(requestMsg)), verbose(verbose)
    {}

  private:
    PldmTransport* pldmTransport; //!< PLDM transport
    mctp_eid_t eid;               //!< endpoint ID of the remote MCTP endpoint
    pldm::Request requestMsg;     //!< PLDM request message
    bool verbose;                 //!< verbose tracing flag

    /** @brief Sends the PLDM request message on the socket
     *
     *  @return return PLDM_SUCCESS on success and PLDM_ERROR otherwise
     */
    int send() const override
    {
        if (verbose)
        {
            pldm::utils::printBuffer(pldm::utils::Tx, requestMsg);
        }
        pldm::flightrecorder::FlightRecorder::GetInstance().saveRecord(
            requestMsg, true);
        const struct pldm_msg_hdr* hdr =
            (struct pldm_msg_hdr*)(requestMsg.data());
        if (!hdr->request)
        {
            return PLDM_REQUESTER_NOT_REQ_MSG;
        }

        if (pldmTransport == nullptr)
        {
            error("Invalid transport: Unable to send PLDM request");
            return PLDM_ERROR;
        }

        auto rc = pldmTransport->sendMsg(static_cast<pldm_tid_t>(eid),
                                         requestMsg.data(), requestMsg.size());
        if (rc < 0)
        {
            error(
                "Failed to send pldmTransport message, response code '{RC}' and error - {ERROR}",
                "RC", rc, "ERROR", errno);
            return PLDM_ERROR;
        }
        return PLDM_SUCCESS;
    }
};

} // namespace requester

} // namespace pldm
