#include "android/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 "android/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;

    CLAMP_MAC_TIMEOUT(duration);

    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);
}
