/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *
 * @author Mladen Turk
 * @version $Id: poll.c 1667243 2015-03-17 10:28:05Z markt $
 */

#include "tcn.h"

#ifdef TCN_DO_STATISTICS
static int sp_created       = 0;
static int sp_destroyed     = 0;
static int sp_cleared       = 0;
#endif

/* Internal poll structure for queryset
 */
typedef struct tcn_pollset {
    apr_pool_t    *pool;
    apr_int32_t   nelts;
    apr_int32_t   nalloc;
    apr_pollset_t *pollset;
    jlong         *set;
    apr_interval_time_t default_timeout;
    /* A ring containing all of the pollfd_t that are active
     */
    APR_RING_HEAD(pfd_poll_ring_t, tcn_pfde_t) poll_ring;
    /* A ring of pollfd_t that have been used, and then _remove()'d
     */
    APR_RING_HEAD(pfd_free_ring_t, tcn_pfde_t) free_ring;
    /* A ring of pollfd_t where rings that have been _remove()`ed but
     * might still be inside a _poll()
     */
    APR_RING_HEAD(pfd_dead_ring_t, tcn_pfde_t) dead_ring;
#ifdef TCN_DO_STATISTICS
    int sp_added;
    int sp_max_count;
    int sp_poll;
    int sp_polled;
    int sp_max_polled;
    int sp_remove;
    int sp_removed;
    int sp_maintained;
    int sp_max_maintained;
    int sp_err_poll;
    int sp_poll_timeout;
    int sp_overflow;
    int sp_equals;
    int sp_eintr;
#endif
} tcn_pollset_t;

#ifdef TCN_DO_STATISTICS
static void sp_poll_statistics(tcn_pollset_t *p)
{
    fprintf(stderr, "Pollset Statistics ......\n");
    fprintf(stderr, "Number of added sockets : %d\n", p->sp_added);
    fprintf(stderr, "Max. number of sockets  : %d\n", p->sp_max_count);
    fprintf(stderr, "Poll calls              : %d\n", p->sp_poll);
    fprintf(stderr, "Poll timeouts           : %d\n", p->sp_poll_timeout);
    fprintf(stderr, "Poll errors             : %d\n", p->sp_err_poll);
    fprintf(stderr, "Poll overflows          : %d\n", p->sp_overflow);
    fprintf(stderr, "Polled sockets          : %d\n", p->sp_polled);
    fprintf(stderr, "Max. Polled sockets     : %d\n", p->sp_max_polled);
    fprintf(stderr, "Poll remove             : %d\n", p->sp_remove);
    fprintf(stderr, "Total removed           : %d\n", p->sp_removed);
    fprintf(stderr, "Maintained              : %d\n", p->sp_maintained);
    fprintf(stderr, "Max. maintained         : %d\n", p->sp_max_maintained);
    fprintf(stderr, "Number of duplicates    : %d\n", p->sp_equals);
    fprintf(stderr, "Number of interrupts    : %d\n", p->sp_eintr);

}

static apr_status_t sp_poll_cleanup(void *data)
{
    sp_cleared++;
    sp_poll_statistics(data);
    return APR_SUCCESS;
}

void sp_poll_dump_statistics()
{
    fprintf(stderr, "Poll Statistics .........\n");
    fprintf(stderr, "Polls created           : %d\n", sp_created);
    fprintf(stderr, "Polls destroyed         : %d\n", sp_destroyed);
    fprintf(stderr, "Polls cleared           : %d\n", sp_cleared);
}
#endif

TCN_IMPLEMENT_CALL(jlong, Poll, create)(TCN_STDARGS, jint size,
                                        jlong pool, jint flags,
                                        jlong default_timeout)
{
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_pollset_t *pollset = NULL;
    tcn_pollset_t *tps = NULL;
    apr_uint32_t f = (apr_uint32_t)flags | APR_POLLSET_NOCOPY;
    UNREFERENCED(o);
    TCN_ASSERT(pool != 0);

    if (f & APR_POLLSET_THREADSAFE) {
        apr_status_t rv = apr_pollset_create(&pollset, (apr_uint32_t)size, p, f);
        if (rv == APR_ENOTIMPL)
            f &= ~APR_POLLSET_THREADSAFE;
        else if (rv != APR_SUCCESS) {
            tcn_ThrowAPRException(e, rv);
            goto cleanup;
        }
    }
    if (pollset == NULL) {
        TCN_THROW_IF_ERR(apr_pollset_create(&pollset,
                         (apr_uint32_t)size, p, f), pollset);
    }
    tps = apr_pcalloc(p, sizeof(tcn_pollset_t));
    TCN_CHECK_ALLOCATED(tps);
    tps->pollset = pollset;
    tps->set     = apr_pcalloc(p, size * sizeof(jlong) * 2);
    TCN_CHECK_ALLOCATED(tps->set);
    APR_RING_INIT(&tps->poll_ring, tcn_pfde_t, link);
    APR_RING_INIT(&tps->free_ring, tcn_pfde_t, link);
    APR_RING_INIT(&tps->dead_ring, tcn_pfde_t, link);

    tps->nelts  = 0;
    tps->nalloc = size;
    tps->pool   = p;
    tps->default_timeout = J2T(default_timeout);
#ifdef TCN_DO_STATISTICS
    sp_created++;
    apr_pool_cleanup_register(p, (const void *)tps,
                              sp_poll_cleanup,
                              apr_pool_cleanup_null);
#endif
cleanup:
    return P2J(tps);
}

TCN_IMPLEMENT_CALL(jint, Poll, destroy)(TCN_STDARGS, jlong pollset)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(pollset != 0);
#ifdef TCN_DO_STATISTICS
    sp_destroyed++;
    apr_pool_cleanup_kill(p->pool, p, sp_poll_cleanup);
    sp_poll_statistics(p);
#endif
    return (jint)apr_pollset_destroy(p->pollset);
}

static apr_status_t do_add(tcn_pollset_t *p, tcn_socket_t *s,
                           apr_int16_t reqevents,
                           apr_interval_time_t socket_timeout)
{

    apr_status_t rv;
    apr_interval_time_t timeout = socket_timeout;
    tcn_pfde_t *elem = NULL;

    if (p->nelts == p->nalloc) {
#ifdef TCN_DO_STATISTICS
        p->sp_overflow++;
#endif
        return APR_ENOMEM;
    }
    if (s->pe != NULL) {
        /* Socket is already added to the pollset.
         */
#ifdef TCN_DO_STATISTICS
        p->sp_equals++;
#endif
        return APR_EEXIST;
    }
    if (timeout == TCN_NO_SOCKET_TIMEOUT) {
        timeout = p->default_timeout;
    }
    if (timeout > 0)
        s->last_active = apr_time_now();
    else
        s->last_active = 0;
    s->timeout = socket_timeout;
    if (!APR_RING_EMPTY(&p->free_ring, tcn_pfde_t, link)) {
        elem = APR_RING_FIRST(&p->free_ring);
        APR_RING_REMOVE(elem, link);
    }
    else {
        elem = (tcn_pfde_t *)apr_palloc(p->pool, sizeof(tcn_pfde_t));
        APR_RING_ELEM_INIT(elem, link);
    }
    elem->fd.reqevents   = reqevents;
    elem->fd.desc_type   = APR_POLL_SOCKET;
    elem->fd.desc.s      = s->sock;
    elem->fd.client_data = s;
#ifdef TCN_DO_STATISTICS
    p->sp_added++;
    p->sp_max_count = TCN_MAX(p->sp_max_count, p->sp_added);
#endif
    rv = apr_pollset_add(p->pollset, &elem->fd);
    if (rv != APR_SUCCESS) {
        APR_RING_INSERT_TAIL(&p->free_ring, elem, tcn_pfde_t, link);
    }
    else {
        APR_RING_INSERT_TAIL(&p->poll_ring, elem, tcn_pfde_t, link);
        s->pe = elem;
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Poll, add)(TCN_STDARGS, jlong pollset,
                                    jlong socket, jint reqevents)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    tcn_socket_t *s  = J2P(socket, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(socket != 0);

    return (jint) do_add(p, s, (apr_int16_t)reqevents, TCN_NO_SOCKET_TIMEOUT);
}

TCN_IMPLEMENT_CALL(jint, Poll, addWithTimeout)(TCN_STDARGS, jlong pollset,
                                               jlong socket, jint reqevents,
                                               jlong socket_timeout)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    tcn_socket_t *s  = J2P(socket, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(socket != 0);

    return (jint) do_add(p, s, (apr_int16_t)reqevents, J2T(socket_timeout));
}

TCN_IMPLEMENT_CALL(jint, Poll, remove)(TCN_STDARGS, jlong pollset,
                                       jlong socket)
{
    apr_pollfd_t fd;
    apr_status_t rv;
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    tcn_socket_t  *s = J2P(socket, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(socket != 0);

    if (s->pe == NULL) {
        /* Already removed */
        return APR_NOTFOUND;
    }
    fd.desc_type   = APR_POLL_SOCKET;
    fd.desc.s      = s->sock;
    fd.client_data = s;
    fd.reqevents   = APR_POLLIN | APR_POLLOUT;
#ifdef TCN_DO_STATISTICS
    p->sp_remove++;
#endif

    rv = apr_pollset_remove(p->pollset, &fd);
    APR_RING_REMOVE(s->pe, link);
    APR_RING_INSERT_TAIL(&p->dead_ring, s->pe, tcn_pfde_t, link);
    s->pe = NULL;
    p->nelts--;
#ifdef TCN_DO_STATISTICS
    p->sp_removed++;
#endif
    return rv;
}


TCN_IMPLEMENT_CALL(jint, Poll, poll)(TCN_STDARGS, jlong pollset,
                                     jlong timeout, jlongArray set,
                                     jboolean remove)
{
    const apr_pollfd_t *fd = NULL;
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    apr_int32_t  i, num = 0;
    apr_status_t rv = APR_SUCCESS;
    apr_time_t now = 0;
    apr_interval_time_t ptime = J2T(timeout);
    UNREFERENCED(o);
    TCN_ASSERT(pollset != 0);

#ifdef TCN_DO_STATISTICS
     p->sp_poll++;
#endif

    if (ptime > 0) {
        tcn_pfde_t  *ep;

        now = apr_time_now();
        /* Find the minimum timeout */
        APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link)
        {
            apr_interval_time_t socket_timeout = 0;
            tcn_socket_t *s = (tcn_socket_t *)ep->fd.client_data;
            if (s->timeout == TCN_NO_SOCKET_TIMEOUT) {
                socket_timeout = p->default_timeout;
            }
            else {
                socket_timeout = s->timeout;
            }
            if (socket_timeout >= 0) {
                apr_interval_time_t t = now - s->last_active;
                if (t >= socket_timeout) {
                    ptime = 0;
                    break;
                }
                else {
                    ptime = TCN_MIN(socket_timeout - t, ptime);
                }
            }
        }
    }
    else if (ptime < 0)
        ptime = 0;
    for (;;) {
        rv = apr_pollset_poll(p->pollset, ptime, &num, &fd);
        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_EINTR(rv)) {
#ifdef TCN_DO_STATISTICS
                p->sp_eintr++;
#endif
                continue;
            }
            TCN_ERROR_WRAP(rv);
#ifdef TCN_DO_STATISTICS
            if (rv == TCN_TIMEUP)
                p->sp_poll_timeout++;
            else
                p->sp_err_poll++;
#endif
            num = (apr_int32_t)(-rv);
        }
        break;
    }
    /* Shift all PFDs in the Dead Ring to the Free Ring */
    APR_RING_CONCAT(&p->free_ring, &p->dead_ring, tcn_pfde_t, link);
    if (num > 0) {
#ifdef TCN_DO_STATISTICS
         p->sp_polled += num;
         p->sp_max_polled = TCN_MAX(p->sp_max_polled, num);
#endif
        if (!remove)
            now = apr_time_now();
        for (i = 0; i < num; i++) {
            tcn_socket_t *s = (tcn_socket_t *)fd->client_data;
            p->set[i*2+0] = (jlong)(fd->rtnevents);
            p->set[i*2+1] = P2J(s);
            /* If a socket is registered for multiple events and the poller has
               multiple events to return it may do as a single pair in this
               array or as multiple pairs depending on implementation. On OSX at
               least, multiple pairs have been observed. In this case do not try
               and remove socket from the pollset for a second time else a crash
               will result. */ 
            if (remove) {
                if (s->pe) {
                    apr_pollset_remove(p->pollset, fd);
                    APR_RING_REMOVE(s->pe, link);
                    APR_RING_INSERT_TAIL(&p->dead_ring, s->pe, tcn_pfde_t, link);
                    s->pe = NULL;
                    p->nelts--;
#ifdef TCN_DO_STATISTICS
                    p->sp_removed++;
#endif
                }
            }
            else {
                /* Update last active with the current time
                 * after the poll call.
                 */
                s->last_active = now;
            }
            fd ++;
        }
        (*e)->SetLongArrayRegion(e, set, 0, num * 2, p->set);
    }

    return (jint)num;
}

TCN_IMPLEMENT_CALL(jint, Poll, maintain)(TCN_STDARGS, jlong pollset,
                                         jlongArray set, jboolean remove)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    apr_int32_t  i = 0, num = 0;
    apr_time_t now = apr_time_now();
    tcn_pfde_t   *ep, *ip;

    UNREFERENCED(o);
    TCN_ASSERT(pollset != 0);

    /* Check for timeout sockets */
    APR_RING_FOREACH_SAFE(ep, ip, &p->poll_ring, tcn_pfde_t, link)
    {
        apr_interval_time_t timeout = 0;
        tcn_socket_t *s = (tcn_socket_t *)ep->fd.client_data;
        if (s->timeout == TCN_NO_SOCKET_TIMEOUT) {
            timeout = p->default_timeout;
        }
        else {
            timeout = s->timeout;
        }
        if (timeout == -1) {
            continue;
        }
        if ((now - s->last_active) >= timeout) {
            p->set[num++] = P2J(s);
            if (remove) {
                APR_RING_REMOVE(ep, link);
                APR_RING_INSERT_TAIL(&p->dead_ring, ep, tcn_pfde_t, link);
                s->pe = NULL;
                p->nelts--;
#ifdef TCN_DO_STATISTICS
                p->sp_removed++;
#endif
            }
        }
    }
    if (num) {
#ifdef TCN_DO_STATISTICS
        p->sp_maintained += num;
        p->sp_max_maintained = TCN_MAX(p->sp_max_maintained, num);
#endif
        if (remove) {
            for (i = 0; i < num; i++) {
                apr_pollfd_t fd;
                tcn_socket_t *s = J2P(p->set[i], tcn_socket_t *);
                fd.desc_type    = APR_POLL_SOCKET;
                fd.desc.s       = s->sock;
                fd.client_data  = s;
                fd.reqevents    = APR_POLLIN | APR_POLLOUT;
                apr_pollset_remove(p->pollset, &fd);
            }
        }
        (*e)->SetLongArrayRegion(e, set, 0, num, p->set);
    }
    return (jint)num;
}

TCN_IMPLEMENT_CALL(void, Poll, setTtl)(TCN_STDARGS, jlong pollset,
                                       jlong default_timeout)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    UNREFERENCED_STDARGS;
    p->default_timeout = J2T(default_timeout);
}

TCN_IMPLEMENT_CALL(jlong, Poll, getTtl)(TCN_STDARGS, jlong pollset)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    UNREFERENCED_STDARGS;
    return (jlong)p->default_timeout;
}

TCN_IMPLEMENT_CALL(jint, Poll, pollset)(TCN_STDARGS, jlong pollset,
                                        jlongArray set)
{
    tcn_pollset_t *p = J2P(pollset,  tcn_pollset_t *);
    apr_int32_t n = 0;
    tcn_pfde_t *ep;

    UNREFERENCED(o);
    TCN_ASSERT(pollset != 0);

    APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link)
    {
        apr_pollfd_t *fd = &ep->fd;
        fd->rtnevents = APR_POLLHUP | APR_POLLIN;
        p->set[n++]   = (jlong)(fd->rtnevents);
        p->set[n++]   = P2J(fd->client_data);
    }
    if (n > 0)
        (*e)->SetLongArrayRegion(e, set, 0, n, p->set);
    return n / 2;
}
