#include "sock_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 = static_cast<socklen_t>(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 = static_cast<socklen_t>(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

