/* $Id$
 */
#include "test.h"
#include <pjlib.h>
#include <pj/compat/high_precision.h>

#if INCLUDE_ECHO_SERVER

static pj_bool_t thread_quit_flag;

struct server
{
    pj_pool_t          *pool;
    int                 sock_type;
    int                 thread_count;
    pj_ioqueue_t       *ioqueue;
    pj_sock_t           sock;
    pj_sock_t           client_sock;
    pj_ioqueue_key_t   *key;
    pj_ioqueue_callback cb;
    char               *buf;
    pj_size_t           bufsize;
    pj_sockaddr_in      addr;
    int                 addrlen;
    pj_size_t           bytes_recv;
    pj_timestamp        start_time;
};

static void on_read_complete(pj_ioqueue_key_t *key, pj_ssize_t bytes_read)
{
    struct server *server = pj_ioqueue_get_user_data(key);
    pj_status_t rc;

    if (server->sock_type == PJ_SOCK_DGRAM) {
        if (bytes_read > 0) {
            /* Send data back to sender. */
            rc = pj_ioqueue_sendto( server->ioqueue, server->key, 
                                    server->buf, bytes_read, 0,
                                    &server->addr, server->addrlen);
            if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
                app_perror("...sendto() error", rc);
            }
        } else {
            PJ_LOG(3,("", "...read error (bytes_read=%d)", bytes_read));
        }

        /* Start next receive. */
        rc = pj_ioqueue_recvfrom( server->ioqueue, server->key,
                                  server->buf, server->bufsize, 0,
                                  &server->addr, &server->addrlen);
        if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
            app_perror("...recvfrom() error", rc);
        }

    } 
    else if (server->sock_type == PJ_SOCK_STREAM) {
        if (bytes_read > 0) {
            /* Send data back to sender. */
            rc = pj_ioqueue_send( server->ioqueue, server->key,
                                  server->buf, bytes_read, 0);
            if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
                app_perror("...send() error", rc);
                bytes_read = 0;
            }
        }

        if (bytes_read <= 0) {
            PJ_LOG(3,("", "...tcp closed"));
            pj_ioqueue_unregister( server->ioqueue, server->key );
            pj_sock_close( server->sock );
            pj_pool_release( server->pool );
            return;
        }

        /* Start next receive. */
        rc = pj_ioqueue_recv( server->ioqueue, server->key,
                              server->buf, server->bufsize, 0);
        if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
            app_perror("...recv() error", rc);
        }
    }

    /* Add counter. */
    if (bytes_read > 0) {
        if (server->bytes_recv == 0) {
            pj_get_timestamp(&server->start_time);
            server->bytes_recv += bytes_read;
        } else {
            enum { USECS_IN_SECOND = 1000000 };
            pj_timestamp now;
            pj_uint32_t usec_elapsed;

            server->bytes_recv += bytes_read;

            pj_get_timestamp(&now);
            usec_elapsed = pj_elapsed_usec(&server->start_time, &now);
            if (usec_elapsed > USECS_IN_SECOND) {
                if (usec_elapsed < 2 * USECS_IN_SECOND) {
                    pj_highprec_t bw;
                    pj_uint32_t bw32;
                    const char *type_name;

                    /* bandwidth(bw) = server->bytes_recv * USECS/elapsed */
                    bw = server->bytes_recv;
                    pj_highprec_mul(bw, USECS_IN_SECOND);
                    pj_highprec_div(bw, usec_elapsed);

                    bw32 = (pj_uint32_t) bw;

                    if (server->sock_type==PJ_SOCK_STREAM)
                        type_name = "tcp";
                    else if (server->sock_type==PJ_SOCK_DGRAM)
                        type_name = "udp";
                    else
                        type_name = "???";

                    PJ_LOG(3,("",
                              "...[%s:%d (%d threads)] Current bandwidth=%u KBps",
                              type_name, 
                              ECHO_SERVER_START_PORT+server->thread_count,
                              server->thread_count,
                              bw32/1024));
                }
                server->start_time = now;
                server->bytes_recv = 0;
            }
        }
    }
}

static void on_accept_complete( pj_ioqueue_key_t *key, pj_sock_t sock,
				int status)
{
    struct server *server_server = pj_ioqueue_get_user_data(key);
    pj_status_t rc;

    PJ_UNUSED_ARG(sock);

    if (status == 0) {
        pj_pool_t *pool;
        struct server *new_server;

        pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
        new_server = pj_pool_zalloc(pool, sizeof(struct server));

        new_server->pool = pool;
        new_server->ioqueue = server_server->ioqueue;
        new_server->sock_type = server_server->sock_type;
        new_server->thread_count = server_server->thread_count;
        new_server->sock = server_server->client_sock;
        new_server->bufsize = 4096;
        new_server->buf = pj_pool_alloc(pool, new_server->bufsize);
        new_server->cb = server_server->cb;

        rc = pj_ioqueue_register_sock( new_server->pool, new_server->ioqueue, 
                                       new_server->sock, new_server,
                                       &server_server->cb, &new_server->key);
        if (rc != PJ_SUCCESS) {
            app_perror("...registering new tcp sock", rc);
            pj_sock_close(new_server->sock);
            pj_pool_release(pool);
            thread_quit_flag = 1;
            return;
        }

        rc = pj_ioqueue_recv( new_server->ioqueue, new_server->key, 
                              new_server->buf, new_server->bufsize, 0);
        if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
            app_perror("...recv() error", rc);
            pj_sock_close(new_server->sock);
            pj_pool_release(pool);
            thread_quit_flag = 1;
            return;
        }
    }

    rc = pj_ioqueue_accept( server_server->ioqueue, server_server->key,
                            &server_server->client_sock,
                            NULL, NULL, NULL);
    if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
        app_perror("...accept() error", rc);
        thread_quit_flag = 1;
    }
}

static int thread_proc(void *arg)
{
    pj_ioqueue_t *ioqueue = arg;

    while (!thread_quit_flag) {
        pj_time_val timeout;
        int count;

        timeout.sec = 0; timeout.msec = 50;
        count = pj_ioqueue_poll( ioqueue, &timeout );
        if (count > 0) {
            count = 0;
        }
    }

    return 0;
}

static int start_echo_server( int sock_type, int port, int thread_count )
{
    pj_pool_t *pool;
    struct server *server;
    int i;
    pj_status_t rc;


    pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
    if (!pool) 
        return -10;

    server = pj_pool_zalloc(pool, sizeof(struct server));

    server->sock_type = sock_type;
    server->thread_count = thread_count;
    server->cb.on_read_complete = &on_read_complete;
    server->cb.on_accept_complete = &on_accept_complete;

    /* create ioqueue */
    rc = pj_ioqueue_create( pool, 32, thread_count, &server->ioqueue);
    if (rc != PJ_SUCCESS) {
        app_perror("...error creating ioqueue", rc);
        return -20;
    }
    
    /* create and register socket to ioqueue. */
    rc = app_socket(PJ_AF_INET, sock_type, 0, port, &server->sock);
    if (rc != PJ_SUCCESS) {
        app_perror("...error initializing socket", rc);
        return -30;
    }

    rc = pj_ioqueue_register_sock( pool, server->ioqueue, 
                                   server->sock, 
                                   server, &server->cb, 
                                   &server->key);
    if (rc != PJ_SUCCESS) {
        app_perror("...error registering socket to ioqueue", rc);
        return -40;
    }

    /* create receive buffer. */
    server->bufsize = 4096;
    server->buf = pj_pool_alloc(pool, server->bufsize);

    if (sock_type == PJ_SOCK_DGRAM) {
        server->addrlen = sizeof(server->addr);
        rc = pj_ioqueue_recvfrom( server->ioqueue, server->key,
                                  server->buf, server->bufsize,
                                  0,
                                  &server->addr, &server->addrlen);
        if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
            app_perror("...read error", rc);
            return -50;
        }
    } else {
        rc = pj_ioqueue_accept( server->ioqueue, server->key,
                                &server->client_sock, NULL, NULL, NULL );
        if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
            app_perror("...accept() error", rc);
            return -60;
        }
    }

    /* create threads. */
    
    for (i=0; i<thread_count; ++i) {
        pj_thread_t *thread;
        rc = pj_thread_create(pool, NULL, &thread_proc, server->ioqueue,
                              PJ_THREAD_DEFAULT_STACK_SIZE, 0, &thread);
        if (rc != PJ_SUCCESS) {
            app_perror("...unable to create thread", rc);
            return -70;
        }
    }
    
    /* Done. */
    return PJ_SUCCESS;
}

int echo_server(void)
{
    enum { MAX_THREADS = 4 };
    int sock_types[2];
    int i, j, rc;

    sock_types[0] = PJ_SOCK_DGRAM;
    sock_types[1] = PJ_SOCK_STREAM;

    for (i=0; i<2; ++i) {
        for (j=0; j<MAX_THREADS; ++j) {
            rc = start_echo_server(sock_types[i], ECHO_SERVER_START_PORT+j, j+1);
            if (rc != 0)
                return rc;
        }
    }

    pj_thread_sleep(100);
    PJ_LOG(3,("", "Echo server started in port %d - %d", 
              ECHO_SERVER_START_PORT, ECHO_SERVER_START_PORT + MAX_THREADS));

    PJ_LOG(3,("", "Press Ctrl-C to quit"));

    for (;!thread_quit_flag;) {
        pj_thread_sleep(1000);
    }

    return 0;
}


#else
int dummy_echo_server;
#endif  /* INCLUDE_ECHO_SERVER */

