#pragma once
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <boost/asio/ip/udp.hpp>
#include <memory>
#include <optional>
#include <phosphor-logging/log.hpp>
#include <string>
#include <tuple>
#include <variant>
#include <vector>

namespace udpsocket
{

/** @class Channel
 *
 *  @brief Provides encapsulation for UDP socket operations like Read, Peek,
 *         Write, Remote peer's IP Address and Port.
 */
class Channel
{
  public:
    Channel() = delete;
    ~Channel() = default;
    Channel(const Channel& right) = delete;
    Channel& operator=(const Channel& right) = delete;
    Channel(Channel&&) = delete;
    Channel& operator=(Channel&&) = delete;

    /**
     * @brief Constructor
     *
     * Initialize the IPMI socket object with the socket descriptor
     *
     * @param [in] pointer to a boost::asio udp socket object
     *
     * @return None
     */
    explicit Channel(std::shared_ptr<boost::asio::ip::udp::socket> socket) :
        socket(socket)
    {
    }

    /**
     * @brief Fetch the IP address of the remote peer
     *
     * Returns the IP address of the remote peer which is connected to this
     * socket
     *
     * @return IP address of the remote peer
     */
    std::string getRemoteAddress() const
    {
        const char* retval = nullptr;
        if (sockAddrSize == sizeof(sockaddr_in))
        {
            char ipv4addr[INET_ADDRSTRLEN];
            retval =
                inet_ntop(AF_INET, &remoteSockAddr, ipv4addr, sizeof(ipv4addr));
        }
        else if (sockAddrSize == sizeof(sockaddr_in6))
        {
            char ipv6addr[INET6_ADDRSTRLEN];
            retval = inet_ntop(AF_INET6, &remoteSockAddr, ipv6addr,
                               sizeof(ipv6addr));
        }
        if (retval)
        {
            return retval;
        }
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Error in inet_ntop",
            phosphor::logging::entry("ERROR=%s", strerror(errno)));
        return std::string();
    }

    /**
     * @brief Fetch the port number of the remote peer
     *
     * Returns the port number of the remote peer
     *
     * @return Port number
     *
     */
    uint16_t getPort() const
    {
        if (sockAddrSize == sizeof(sockaddr_in))
        {
            return ntohs(reinterpret_cast<const sockaddr_in*>(&remoteSockAddr)
                             ->sin_port);
        }
        if (sockAddrSize == sizeof(sockaddr_in6))
        {
            return ntohs(reinterpret_cast<const sockaddr_in6*>(&remoteSockAddr)
                             ->sin6_port);
        }
        return 0;
    }

    /**
     * @brief Read the incoming packet
     *
     * Reads the data available on the socket
     *
     * @return A tuple with return code and vector with the buffer
     *         In case of success, the vector is populated with the data
     *         available on the socket and return code is 0.
     *         In case of error, the return code is < 0 and vector is set
     *         to size 0.
     */
    std::tuple<int, std::vector<uint8_t>> read()
    {
        // cannot use the standard asio reading mechanism because it does not
        // provide a mechanism to reach down into the depths and use a msghdr
        std::vector<uint8_t> packet(socket->available());
        iovec iov = {packet.data(), packet.size()};
        char msgCtrl[1024];
        msghdr msg = {&remoteSockAddr, sizeof(remoteSockAddr), &iov, 1,
                      msgCtrl,         sizeof(msgCtrl),        0};

        ssize_t bytesReceived = recvmsg(socket->native_handle(), &msg, 0);
        // Read of the packet failed
        if (bytesReceived < 0)
        {
            // something bad happened; bail
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Error in recvmsg",
                phosphor::logging::entry("ERROR=%s", strerror(errno)));
            return std::make_tuple(-errno, std::vector<uint8_t>());
        }
        // save the size of either ipv4 or i4v6 sockaddr
        sockAddrSize = msg.msg_namelen;

        // extract the destination address from the message
        cmsghdr* cmsg;
        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != 0;
             cmsg = CMSG_NXTHDR(&msg, cmsg))
        {
            if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
            {
                // save local address from the pktinfo4
                pktinfo4 = *reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
            }
            if (cmsg->cmsg_level == IPPROTO_IPV6 &&
                cmsg->cmsg_type == IPV6_PKTINFO)
            {
                // save local address from the pktinfo6
                pktinfo6 = *reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
            }
        }
        return std::make_tuple(0, packet);
    }

    /**
     *  @brief Write the outgoing packet
     *
     *  Writes the data in the vector to the socket
     *
     *  @param [in] inBuffer
     *      The vector would be the buffer of data to write to the socket.
     *
     *  @return In case of success the return code is the number of bytes
     *          written and return code is < 0 in case of failure.
     */
    int write(const std::vector<uint8_t>& inBuffer)
    {
        // in order to make sure packets go back out from the same
        // IP address they came in on, sendmsg must be used instead
        // of the boost::asio::ip::send or sendto
        iovec iov = {const_cast<uint8_t*>(inBuffer.data()), inBuffer.size()};
        char msgCtrl[1024];
        msghdr msg = {&remoteSockAddr, sockAddrSize,    &iov, 1,
                      msgCtrl,         sizeof(msgCtrl), 0};
        int cmsg_space = 0;
        cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
        if (pktinfo6)
        {
            cmsg->cmsg_level = IPPROTO_IPV6;
            cmsg->cmsg_type = IPV6_PKTINFO;
            cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
            *reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg)) = *pktinfo6;
            cmsg_space += CMSG_SPACE(sizeof(in6_pktinfo));
        }
        else if (pktinfo4)
        {
            cmsg->cmsg_level = IPPROTO_IP;
            cmsg->cmsg_type = IP_PKTINFO;
            cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
            *reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg)) = *pktinfo4;
            cmsg_space += CMSG_SPACE(sizeof(in_pktinfo));
        }
        msg.msg_controllen = cmsg_space;
        int ret = sendmsg(socket->native_handle(), &msg, 0);
        if (ret < 0)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Error in sendmsg",
                phosphor::logging::entry("ERROR=%s", strerror(errno)));
        }
        return ret;
    }

    /**
     * @brief Returns file descriptor for the socket
     */
    auto getHandle(void) const
    {
        return socket->native_handle();
    }

  private:
    std::shared_ptr<boost::asio::ip::udp::socket> socket;
    sockaddr_storage remoteSockAddr;
    socklen_t sockAddrSize;
    std::optional<in_pktinfo> pktinfo4;
    std::optional<in6_pktinfo> pktinfo6;
};

} // namespace udpsocket
