#include "iolooper.h"
#include "qemu-common.h"

/* An implementation of iolooper.h based on Unix select() */
#ifdef _WIN32
#  include <winsock2.h>
#else
#  include <sys/types.h>
#  include <sys/select.h>
#endif
#include "sockets.h"

struct IoLooper {
    fd_set   reads[1];
    fd_set   writes[1];
    fd_set   reads_result[1];
    fd_set   writes_result[1];
    int      max_fd;
    int      max_fd_valid;
};

IoLooper*
iolooper_new(void)
{
    IoLooper*  iol = malloc(sizeof(*iol));
    iolooper_reset(iol);
    return iol;
}

void
iolooper_free( IoLooper*  iol )
{
    free(iol);
}

void
iolooper_reset( IoLooper*  iol )
{
    FD_ZERO(iol->reads);
    FD_ZERO(iol->writes);
    iol->max_fd = -1;
    iol->max_fd_valid = 1;
}

static void
iolooper_add_fd( IoLooper*  iol, int fd )
{
    if (iol->max_fd_valid && fd > iol->max_fd) {
        iol->max_fd = fd;
    }
}

static void
iolooper_del_fd( IoLooper*  iol, int fd )
{
    if (iol->max_fd_valid && fd == iol->max_fd)
        iol->max_fd_valid = 0;
}

void
iolooper_modify( IoLooper* iol, int fd, int oldflags, int newflags )
{
    if (fd < 0)
        return;

    int changed = oldflags ^ newflags;

    if ((changed & IOLOOPER_READ) != 0) {
        if ((newflags & IOLOOPER_READ) != 0)
            iolooper_add_read(iol, fd);
        else
            iolooper_del_read(iol, fd);
    }
    if ((changed & IOLOOPER_WRITE) != 0) {
        if ((newflags & IOLOOPER_WRITE) != 0)
            iolooper_add_write(iol, fd);
        else
            iolooper_del_write(iol, fd);
    }
}


static int
iolooper_fd_count( IoLooper*  iol )
{
    int  max_fd = iol->max_fd;
    int  fd;

    if (iol->max_fd_valid)
        return max_fd + 1;

    /* recompute max fd */
    for (fd = 0; fd < FD_SETSIZE; fd++) {
        if (!FD_ISSET(fd, iol->reads) && !FD_ISSET(fd, iol->writes))
            continue;

        max_fd = fd;
    }
    iol->max_fd       = max_fd;
    iol->max_fd_valid = 1;

    return max_fd + 1;
}

void
iolooper_add_read( IoLooper*  iol, int  fd )
{
    if (fd >= 0) {
        iolooper_add_fd(iol, fd);
        FD_SET(fd, iol->reads);
    }
}

void
iolooper_add_write( IoLooper*  iol, int  fd )
{
    if (fd >= 0) {
        iolooper_add_fd(iol, fd);
        FD_SET(fd, iol->writes);
    }
}

void
iolooper_del_read( IoLooper*  iol, int  fd )
{
    if (fd >= 0) {
        iolooper_del_fd(iol, fd);
        FD_CLR(fd, iol->reads);
    }
}

void
iolooper_del_write( IoLooper*  iol, int  fd )
{
    if (fd >= 0) {
        iolooper_del_fd(iol, fd);
        FD_CLR(fd, iol->writes);
    }
}

int
iolooper_poll( IoLooper*  iol )
{
    int     count = iolooper_fd_count(iol);
    int     ret;
    fd_set  errs;

    if (count == 0)
        return 0;

    FD_ZERO(&errs);

    do {
        struct timeval  tv;

        tv.tv_sec = tv.tv_usec = 0;

        iol->reads_result[0]  = iol->reads[0];
        iol->writes_result[0] = iol->writes[0];

        ret = select( count, iol->reads_result, iol->writes_result, &errs, &tv);
    } while (ret < 0 && errno == EINTR);

    return ret;
}

int
iolooper_wait( IoLooper*  iol, int64_t  duration )
{
    int     count = iolooper_fd_count(iol);
    int     ret;
    fd_set  errs;
    struct timeval tm0, *tm = NULL;

    if (count == 0)
        return 0;

    if (duration < 0)
        tm = NULL;
    else {
        tm = &tm0;
        tm->tv_sec  = duration / 1000;
        tm->tv_usec = (duration - 1000*tm->tv_sec) * 1000;
    }

    FD_ZERO(&errs);

    do {
        iol->reads_result[0]  = iol->reads[0];
        iol->writes_result[0] = iol->writes[0];

        ret = select( count, iol->reads_result, iol->writes_result, &errs, tm);
        if (ret == 0) {
            // Indicates timeout
            errno = ETIMEDOUT;
        }
    } while (ret < 0 && errno == EINTR);

    return ret;
}


int
iolooper_is_read( IoLooper*  iol, int  fd )
{
    return FD_ISSET(fd, iol->reads_result);
}

int
iolooper_is_write( IoLooper*  iol, int  fd )
{
    return FD_ISSET(fd, iol->writes_result);
}

int
iolooper_has_operations( IoLooper* iol )
{
    return iolooper_fd_count(iol) > 0;
}

int64_t
iolooper_now(void)
{
    struct timeval time_now;
    return gettimeofday(&time_now, NULL) ? -1 : (int64_t)time_now.tv_sec * 1000LL +
                                                time_now.tv_usec / 1000;
}

int
iolooper_wait_absolute(IoLooper* iol, int64_t deadline)
{
    int64_t timeout = deadline - iolooper_now();

    /* If the deadline has passed, set the timeout to 0, this allows us
     * to poll the file descriptor nonetheless */
    if (timeout < 0)
        timeout = 0;

    return iolooper_wait(iol, timeout);
}
