#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_INET, &address.inAddr.sin_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
