/* $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>

void app_perror(const char *msg, pj_status_t rc)
{
    char errbuf[256];

    PJ_CHECK_STACK();

    pj_strerror(rc, errbuf, sizeof(errbuf));
    PJ_LOG(1,("test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
}

pj_status_t create_stun_config(pj_pool_t *pool, pj_stun_config *stun_cfg)
{
    pj_ioqueue_t *ioqueue;
    pj_timer_heap_t *timer_heap;
    pj_lock_t *lock;
    pj_status_t status;

    status = pj_ioqueue_create(pool, 64, &ioqueue);
    if (status != PJ_SUCCESS) {
	app_perror("   pj_ioqueue_create()", status);
	return status;
    }

    status = pj_timer_heap_create(pool, 256, &timer_heap);
    if (status != PJ_SUCCESS) {
	app_perror("   pj_timer_heap_create()", status);
	pj_ioqueue_destroy(ioqueue);
	return status;
    }

    pj_lock_create_recursive_mutex(pool, NULL, &lock);
    pj_timer_heap_set_lock(timer_heap, lock, PJ_TRUE);

    pj_stun_config_init(stun_cfg, mem, 0, ioqueue, timer_heap);

    return PJ_SUCCESS;
}

void destroy_stun_config(pj_stun_config *stun_cfg)
{
    if (stun_cfg->timer_heap) {
	pj_timer_heap_destroy(stun_cfg->timer_heap);
	stun_cfg->timer_heap = NULL;
    }
    if (stun_cfg->ioqueue) {
	pj_ioqueue_destroy(stun_cfg->ioqueue);
	stun_cfg->ioqueue = NULL;
    }
}

void poll_events(pj_stun_config *stun_cfg, unsigned msec,
		 pj_bool_t first_event_only)
{
    pj_time_val stop_time;
    int count = 0;

    pj_gettimeofday(&stop_time);
    stop_time.msec += msec;
    pj_time_val_normalize(&stop_time);

    /* Process all events for the specified duration. */
    for (;;) {
	pj_time_val timeout = {0, 1}, now;
	int c;

	c = pj_timer_heap_poll( stun_cfg->timer_heap, NULL );
	if (c > 0)
	    count += c;

	//timeout.sec = timeout.msec = 0;
	c = pj_ioqueue_poll( stun_cfg->ioqueue, &timeout);
	if (c > 0)
	    count += c;

	pj_gettimeofday(&now);
	if (PJ_TIME_VAL_GTE(now, stop_time))
	    break;

	if (first_event_only && count >= 0)
	    break;
    }
}

void capture_pjlib_state(pj_stun_config *cfg, struct pjlib_state *st)
{
    pj_caching_pool *cp;

    st->timer_cnt = (unsigned)pj_timer_heap_count(cfg->timer_heap);
    
    cp = (pj_caching_pool*)cfg->pf;
    st->pool_used_cnt = (unsigned)cp->used_count;
}

int check_pjlib_state(pj_stun_config *cfg, 
		      const struct pjlib_state *initial_st)
{
    struct pjlib_state current_state;
    int rc = 0;

    capture_pjlib_state(cfg, &current_state);

    if (current_state.timer_cnt > initial_st->timer_cnt) {
	PJ_LOG(3,("", "    error: possibly leaking timer"));
	rc |= ERR_TIMER_LEAK;

#if PJ_TIMER_DEBUG
	pj_timer_heap_dump(cfg->timer_heap);
#endif
    }

    if (current_state.pool_used_cnt > initial_st->pool_used_cnt) {
	PJ_LOG(3,("", "    error: possibly leaking memory"));
	PJ_LOG(3,("", "    dumping memory pool:"));
	pj_pool_factory_dump(mem, PJ_TRUE);
	rc |= ERR_MEMORY_LEAK;
    }

    return rc;
}


#define DO_TEST(test)	do { \
			    PJ_LOG(3, ("test", "Running %s...", #test));  \
			    rc = test; \
			    PJ_LOG(3, ("test",  \
				       "%s(%d)",  \
				       (char*)(rc ? "..ERROR" : "..success"), rc)); \
			    if (rc!=0) goto on_return; \
			} while (0)


pj_pool_factory *mem;

int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME | 
		      PJ_LOG_HAS_MICRO_SEC;

pj_log_func *orig_log_func;
FILE *log_file;

static void test_log_func(int level, const char *data, int len)
{
    if (log_file) {
	fwrite(data, len, 1, log_file);
    }
    if (level <= 3)
	orig_log_func(level, data, len);
}

static int test_inner(void)
{
    pj_caching_pool caching_pool;
    int rc = 0;

    mem = &caching_pool.factory;

#if 1
    pj_log_set_level(3);
    pj_log_set_decor(param_log_decor);
#elif 1
    log_file = fopen("pjnath-test.log", "wt");
    pj_log_set_level(5);
    orig_log_func = pj_log_get_log_func();
    pj_log_set_log_func(&test_log_func);
#endif

    rc = pj_init();
    if (rc != 0) {
	app_perror("pj_init() error!!", rc);
	return rc;
    }
    
    pj_dump_config();
    pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 );

    pjlib_util_init();
    pjnath_init();

#if INCLUDE_STUN_TEST
    DO_TEST(stun_test());
    DO_TEST(sess_auth_test());
#endif

#if INCLUDE_ICE_TEST
    DO_TEST(ice_test());
#endif

#if INCLUDE_STUN_SOCK_TEST
    DO_TEST(stun_sock_test());
#endif

#if INCLUDE_TURN_SOCK_TEST
    DO_TEST(turn_sock_test());
#endif

#if INCLUDE_CONCUR_TEST
    DO_TEST(concur_test());
#endif

on_return:
    if (log_file)
	fclose(log_file);
    return rc;
}

int test_main(void)
{
    PJ_USE_EXCEPTION;

    PJ_TRY {
        return test_inner();
    }
    PJ_CATCH_ANY {
        int id = PJ_GET_EXCEPTION();
        PJ_LOG(3,("test", "FATAL: unhandled exception id %d (%s)", 
                  id, pj_exception_id_name(id)));
    }
    PJ_END;

    return -1;
}

