#include "socket_channel.hpp"

#include <errno.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>

#include <iostream>
#include <string>

namespace udpsocket
{

std::string Channel::getRemoteAddress() const
{
    char tmp[INET_ADDRSTRLEN] = { 0 };
    inet_ntop(AF_INET6, &address.inAddr.sin6_addr, tmp, sizeof(tmp));
    return std::string(tmp);
}

std::tuple<int, buffer> Channel::read()
{
    int rc = 0;
    int readSize = 0;
    ssize_t readDataLen = 0;
    buffer outBuffer(0);

    if (ioctl(sockfd, FIONREAD, &readSize) < 0)
    {
        std::cerr << "E> Channel::Read : ioctl failed with errno = " << errno;
        rc = -errno;
        return std::make_tuple(rc, std::move(outBuffer));
    }

    outBuffer.resize(readSize);
    auto bufferSize = outBuffer.size();
    auto outputPtr = outBuffer.data();

    address.addrSize = sizeof(address.inAddr);

    do
    {
        readDataLen = recvfrom(sockfd,               // File Descriptor
                               outputPtr ,           // Buffer
                               bufferSize,           // Bytes requested
                               0,                    // Flags
                               &address.sockAddr,    // Address
                               &address.addrSize);   // Address Length

        if (readDataLen > 0) // Data read from the socket
        {
            std::cout << "I> Channel::Read : DataIn Fd[" << sockfd << "] Req["
                      << bufferSize << "] Recv[" << readDataLen << "]\n";
        }
        else if (readDataLen == 0) // Peer has performed an orderly shutdown
        {
            std::cerr << "E> Channel::Read : Connection Closed Fd[" << sockfd
                      << "]\n";
            outBuffer.resize(0);
            rc = -1;
        }
        else if (readDataLen < 0) // Error
        {
            rc = -errno;
            std::cerr << "E> Channel::Read : Receive Error Fd[" << sockfd << "]"
                      << "errno = " << rc << "\n";
            outBuffer.resize(0);
        }
    }
    while ((readDataLen < 0) && (-(rc) == EINTR));

    // Resize the vector to the actual data read from the socket
    outBuffer.resize(readDataLen);
    return std::make_tuple(rc, std::move(outBuffer));
}

int Channel::write(buffer& inBuffer)
{
    int rc = 0;
    auto outputPtr = inBuffer.data();
    auto bufferSize = inBuffer.size();
    auto spuriousWakeup = false;
    ssize_t writeDataLen = 0;
    timeval varTimeout = timeout;

    fd_set writeSet;
    FD_ZERO(&writeSet);
    FD_SET(sockfd, &writeSet);

    do
    {
        spuriousWakeup = false;

        rc = select((sockfd + 1), nullptr, &writeSet, NULL, &varTimeout);

        if (rc > 0)
        {
            if (FD_ISSET(sockfd, &writeSet))
            {
                address.addrSize = sizeof(address.inAddr);
                do
                {
                    writeDataLen = sendto(sockfd,           // File Descriptor
                                          outputPtr,        // Message
                                          bufferSize,       // Length
                                          MSG_NOSIGNAL,     // Flags
                                          &address.sockAddr,// Destination Address
                                          address.addrSize);// Address Length

                    if (writeDataLen < 0)
                    {
                        rc = -errno;
                        std::cerr << "Channel::Write: Write failed with errno:"
                                  << rc << "\n";
                    }
                    else if (static_cast<size_t>(writeDataLen) < bufferSize)
                    {
                        rc = -1;
                        std::cerr << "Channel::Write: Complete data not written"
                                  " to the socket\n";
                    }
                }
                while ((writeDataLen < 0) && (-(rc) == EINTR));
            }
            else
            {
                // Spurious wake up
                std::cerr << "E> Spurious wake up on select (writeset)\n";
                spuriousWakeup = true;
            }
        }
        else
        {
            if (rc == 0)
            {
                // Timed out
                rc = -1;
                std::cerr << "E> We timed out on select call (writeset)\n";
            }
            else
            {
                // Error
                rc  = -errno;
                std::cerr << "E> select call (writeset) had an error : "
                          << rc << "\n";
            }

        }
    }
    while (spuriousWakeup);

    return rc;
}

} // namespace udpsocket
