/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "test.h"
#include <pjlib.h>

#if INCLUDE_ECHO_CLIENT

enum { BUF_SIZE = 512 };

struct client
{
    int sock_type;
    const char *server;
    int port;
};

static pj_atomic_t *totalBytes;
static pj_atomic_t *timeout_counter;
static pj_atomic_t *invalid_counter;

#define MSEC_PRINT_DURATION 1000

static int wait_socket(pj_sock_t sock, unsigned msec_timeout)
{
    pj_fd_set_t fdset;
    pj_time_val timeout;

    timeout.sec = 0;
    timeout.msec = msec_timeout;
    pj_time_val_normalize(&timeout);

    PJ_FD_ZERO(&fdset);
    PJ_FD_SET(sock, &fdset);
    
    return pj_sock_select(FD_SETSIZE, &fdset, NULL, NULL, &timeout);
}

static int echo_client_thread(void *arg)
{
    pj_sock_t sock;
    char send_buf[BUF_SIZE];
    char recv_buf[BUF_SIZE];
    pj_sockaddr_in addr;
    pj_str_t s;
    pj_status_t rc;
    pj_uint32_t buffer_id;
    pj_uint32_t buffer_counter;
    struct client *client = arg;
    pj_status_t last_recv_err = PJ_SUCCESS, last_send_err = PJ_SUCCESS;
    unsigned counter = 0;

    rc = app_socket(pj_AF_INET(), client->sock_type, 0, -1, &sock);
    if (rc != PJ_SUCCESS) {
        app_perror("...unable to create socket", rc);
        return -10;
    }

    rc = pj_sockaddr_in_init( &addr, pj_cstr(&s, client->server), 
                              (pj_uint16_t)client->port);
    if (rc != PJ_SUCCESS) {
        app_perror("...unable to resolve server", rc);
        return -15;
    }

    rc = pj_sock_connect(sock, &addr, sizeof(addr));
    if (rc != PJ_SUCCESS) {
        app_perror("...connect() error", rc);
        pj_sock_close(sock);
        return -20;
    }

    PJ_LOG(3,("", "...socket connected to %s:%d", 
		  pj_inet_ntoa(addr.sin_addr),
		  pj_ntohs(addr.sin_port)));

    pj_memset(send_buf, 'A', BUF_SIZE);
    send_buf[BUF_SIZE-1]='\0';

    /* Give other thread chance to initialize themselves! */
    pj_thread_sleep(200);

    //PJ_LOG(3,("", "...thread %p running", pj_thread_this()));

    buffer_id = (pj_uint32_t) pj_thread_this();
    buffer_counter = 0;

    *(pj_uint32_t*)send_buf = buffer_id;

    for (;;) {
        int rc;
        pj_ssize_t bytes;

	++counter;

	//while (wait_socket(sock,0) > 0)
	//    ;

        /* Send a packet. */
        bytes = BUF_SIZE;
	*(pj_uint32_t*)(send_buf+4) = ++buffer_counter;
        rc = pj_sock_send(sock, send_buf, &bytes, 0);
        if (rc != PJ_SUCCESS || bytes != BUF_SIZE) {
            if (rc != last_send_err) {
                app_perror("...send() error", rc);
                PJ_LOG(3,("", "...ignoring subsequent error.."));
                last_send_err = rc;
                pj_thread_sleep(100);
            }
            continue;
        }

        rc = wait_socket(sock, 500);
        if (rc == 0) {
            PJ_LOG(3,("", "...timeout"));
	    bytes = 0;
	    pj_atomic_inc(timeout_counter);
	} else if (rc < 0) {
	    rc = pj_get_netos_error();
	    app_perror("...select() error", rc);
	    break;
        } else {
            /* Receive back the original packet. */
            bytes = 0;
            do {
                pj_ssize_t received = BUF_SIZE - bytes;
                rc = pj_sock_recv(sock, recv_buf+bytes, &received, 0);
                if (rc != PJ_SUCCESS || received == 0) {
                    if (rc != last_recv_err) {
                        app_perror("...recv() error", rc);
                        PJ_LOG(3,("", "...ignoring subsequent error.."));
                        last_recv_err = rc;
                        pj_thread_sleep(100);
                    }
                    bytes = 0;
		    received = 0;
                    break;
                }
                bytes += received;
            } while (bytes != BUF_SIZE && bytes != 0);
        }

        if (bytes == 0)
            continue;

        if (pj_memcmp(send_buf, recv_buf, BUF_SIZE) != 0) {
	    recv_buf[BUF_SIZE-1] = '\0';
            PJ_LOG(3,("", "...error: buffer %u has changed!\n"
			  "send_buf=%s\n"
			  "recv_buf=%s\n", 
			  counter, send_buf, recv_buf));
	    pj_atomic_inc(invalid_counter);
        }

        /* Accumulate total received. */
	pj_atomic_add(totalBytes, bytes);
    }

    pj_sock_close(sock);
    return 0;
}

int echo_client(int sock_type, const char *server, int port)
{
    pj_pool_t *pool;
    pj_thread_t *thread[ECHO_CLIENT_MAX_THREADS];
    pj_status_t rc;
    struct client client;
    int i;
    pj_atomic_value_t last_received;
    pj_timestamp last_report;

    client.sock_type = sock_type;
    client.server = server;
    client.port = port;

    pool = pj_pool_create( mem, NULL, 4000, 4000, NULL );

    rc = pj_atomic_create(pool, 0, &totalBytes);
    if (rc != PJ_SUCCESS) {
        PJ_LOG(3,("", "...error: unable to create atomic variable", rc));
        return -30;
    }
    rc = pj_atomic_create(pool, 0, &invalid_counter);
    rc = pj_atomic_create(pool, 0, &timeout_counter);

    PJ_LOG(3,("", "Echo client started"));
    PJ_LOG(3,("", "  Destination: %s:%d", 
                  ECHO_SERVER_ADDRESS, ECHO_SERVER_START_PORT));
    PJ_LOG(3,("", "  Press Ctrl-C to exit"));

    for (i=0; i<ECHO_CLIENT_MAX_THREADS; ++i) {
        rc = pj_thread_create( pool, NULL, &echo_client_thread, &client, 
                               PJ_THREAD_DEFAULT_STACK_SIZE, 0,
                               &thread[i]);
        if (rc != PJ_SUCCESS) {
            app_perror("...error: unable to create thread", rc);
            return -10;
        }
    }

    last_received = 0;
    pj_get_timestamp(&last_report);

    for (;;) {
	pj_timestamp now;
	unsigned long received, cur_received;
	unsigned msec;
	pj_highprec_t bw;
	pj_time_val elapsed;
	unsigned bw32;
	pj_uint32_t timeout, invalid;

	pj_thread_sleep(1000);

	pj_get_timestamp(&now);
	elapsed = pj_elapsed_time(&last_report, &now);
	msec = PJ_TIME_VAL_MSEC(elapsed);

	received = pj_atomic_get(totalBytes);
	cur_received = received - last_received;
	
	bw = cur_received;
	pj_highprec_mul(bw, 1000);
	pj_highprec_div(bw, msec);

	bw32 = (unsigned)bw;
	
	last_report = now;
	last_received = received;

	timeout = pj_atomic_get(timeout_counter);
	invalid = pj_atomic_get(invalid_counter);

        PJ_LOG(3,("", 
	          "...%d threads, total bandwidth: %d KB/s, "
		  "timeout=%d, invalid=%d", 
                  ECHO_CLIENT_MAX_THREADS, bw32/1000,
		  timeout, invalid));
    }

    for (i=0; i<ECHO_CLIENT_MAX_THREADS; ++i) {
        pj_thread_join( thread[i] );
    }

    pj_pool_release(pool);
    return 0;
}


#else
int dummy_echo_client;
#endif  /* INCLUDE_ECHO_CLIENT */
