/* $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 <pjsip_ua.h>
#include <pjsip.h>
#include <pjlib.h>

#define THIS_FILE   "inv_offer_answer_test.c"
#define PORT	    5068
#define CONTACT	    "sip:127.0.0.1:5068"
#define TRACE_(x)   PJ_LOG(3,x)

static struct oa_sdp_t
{
    const char *offer;
    const char *answer;
    unsigned	pt_result;
} oa_sdp[] = 
{
    {
	/* Offer: */
	"v=0\r\n"
	"o=alice 1 1 IN IP4 host.anywhere.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.anywhere.com\r\n"
	"t=0 0\r\n"
	"m=audio 49170 RTP/AVP 0\r\n"
	"a=rtpmap:0 PCMU/8000\r\n",

	/* Answer: */
	"v=0\r\n"
	"o=bob 1 1 IN IP4 host.example.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.example.com\r\n"
	"t=0 0\r\n"
	"m=audio 49920 RTP/AVP 0\r\n"
	"a=rtpmap:0 PCMU/8000\r\n"
	"m=video 0 RTP/AVP 31\r\n",

	0
      },

      {
	/* Offer: */
	"v=0\r\n"
	"o=alice 2 2 IN IP4 host.anywhere.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.anywhere.com\r\n"
	"t=0 0\r\n"
	"m=audio 49170 RTP/AVP 8\r\n"
	"a=rtpmap:0 PCMA/8000\r\n",

	/* Answer: */
	"v=0\r\n"
	"o=bob 2 2 IN IP4 host.example.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.example.com\r\n"
	"t=0 0\r\n"
	"m=audio 49920 RTP/AVP 8\r\n"
	"a=rtpmap:0 PCMA/8000\r\n",

	8
      },

      {
	/* Offer: */
	"v=0\r\n"
	"o=alice 3 3 IN IP4 host.anywhere.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.anywhere.com\r\n"
	"t=0 0\r\n"
	"m=audio 49170 RTP/AVP 3\r\n",

	/* Answer: */
	"v=0\r\n"
	"o=bob 3 3 IN IP4 host.example.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.example.com\r\n"
	"t=0 0\r\n"
	"m=audio 49920 RTP/AVP 3\r\n",

	3
      },

      {
	/* Offer: */
	"v=0\r\n"
	"o=alice 4 4 IN IP4 host.anywhere.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.anywhere.com\r\n"
	"t=0 0\r\n"
	"m=audio 49170 RTP/AVP 4\r\n",

	/* Answer: */
	"v=0\r\n"
	"o=bob 4 4 IN IP4 host.example.com\r\n"
	"s= \r\n"
	"c=IN IP4 host.example.com\r\n"
	"t=0 0\r\n"
	"m=audio 49920 RTP/AVP 4\r\n",

	4
    }
};



typedef enum oa_t
{
    OFFERER_NONE,
    OFFERER_UAC,
    OFFERER_UAS
} oa_t;

typedef struct inv_test_param_t
{
    char       *title;
    unsigned	inv_option;
    pj_bool_t	need_established;
    unsigned	count;
    oa_t	oa[4];
} inv_test_param_t;

typedef struct inv_test_t
{
    inv_test_param_t	param;
    pjsip_inv_session  *uac;
    pjsip_inv_session  *uas;

    pj_bool_t		complete;
    pj_bool_t		uas_complete,
			uac_complete;

    unsigned		oa_index;
    unsigned		uac_update_cnt,
			uas_update_cnt;
} inv_test_t;


/**************** GLOBALS ******************/
static inv_test_t   inv_test;
static unsigned	    job_cnt;

typedef enum job_type
{
    SEND_OFFER,
    ESTABLISH_CALL
} job_type;

typedef struct job_t
{
    job_type	    type;
    pjsip_role_e    who;
} job_t;

static job_t jobs[128];


/**************** UTILS ******************/
static pjmedia_sdp_session *create_sdp(pj_pool_t *pool, const char *body)
{
    pjmedia_sdp_session *sdp;
    pj_str_t dup;
    pj_status_t status;
    
    pj_strdup2_with_null(pool, &dup, body);
    status = pjmedia_sdp_parse(pool, dup.ptr, dup.slen, &sdp);
    pj_assert(status == PJ_SUCCESS);

    return sdp;
}

/**************** INVITE SESSION CALLBACKS ******************/
static void on_rx_offer(pjsip_inv_session *inv,
			const pjmedia_sdp_session *offer)
{
    pjmedia_sdp_session *sdp;

    PJ_UNUSED_ARG(offer);

    sdp = create_sdp(inv->dlg->pool, oa_sdp[inv_test.oa_index].answer);
    pjsip_inv_set_sdp_answer(inv, sdp);

    if (inv_test.oa_index == inv_test.param.count-1 &&
	inv_test.param.need_established) 
    {
	jobs[job_cnt].type = ESTABLISH_CALL;
	jobs[job_cnt].who = PJSIP_ROLE_UAS;
	job_cnt++;
    }
}


static void on_create_offer(pjsip_inv_session *inv,
			    pjmedia_sdp_session **p_offer)
{
    PJ_UNUSED_ARG(inv);
    PJ_UNUSED_ARG(p_offer);

    pj_assert(!"Should not happen");
}

static void on_media_update(pjsip_inv_session *inv_ses, 
			    pj_status_t status)
{
    PJ_UNUSED_ARG(status);

    if (inv_ses == inv_test.uas) {
	inv_test.uas_update_cnt++;
	pj_assert(inv_test.uas_update_cnt - inv_test.uac_update_cnt <= 1);
	TRACE_((THIS_FILE, "      Callee media is established"));
    } else if (inv_ses == inv_test.uac) {
	inv_test.uac_update_cnt++;
	pj_assert(inv_test.uac_update_cnt - inv_test.uas_update_cnt <= 1);
	TRACE_((THIS_FILE, "      Caller media is established"));
	
    } else {
	pj_assert(!"Unknown session!");
    }

    if (inv_test.uac_update_cnt == inv_test.uas_update_cnt) {
	inv_test.oa_index++;

	if (inv_test.oa_index < inv_test.param.count) {
	    switch (inv_test.param.oa[inv_test.oa_index]) {
	    case OFFERER_UAC:
		jobs[job_cnt].type = SEND_OFFER;
		jobs[job_cnt].who = PJSIP_ROLE_UAC;
		job_cnt++;
		break;
	    case OFFERER_UAS:
		jobs[job_cnt].type = SEND_OFFER;
		jobs[job_cnt].who = PJSIP_ROLE_UAS;
		job_cnt++;
		break;
	    default:
		pj_assert(!"Invalid oa");
	    }
	}

	pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs));
    }
}

static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
{
    const char *who = NULL;

    PJ_UNUSED_ARG(e);

    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
	TRACE_((THIS_FILE, "      %s call disconnected",
		(inv==inv_test.uas ? "Callee" : "Caller")));
	return;
    }

    if (inv->state != PJSIP_INV_STATE_CONFIRMED)
	return;

    if (inv == inv_test.uas) {
	inv_test.uas_complete = PJ_TRUE;
	who = "Callee";
    } else if (inv == inv_test.uac) {
	inv_test.uac_complete = PJ_TRUE;
	who = "Caller";
    } else
	pj_assert(!"No session");

    TRACE_((THIS_FILE, "      %s call is confirmed", who));

    if (inv_test.uac_complete && inv_test.uas_complete)
	inv_test.complete = PJ_TRUE;
}


/**************** MODULE TO RECEIVE INITIAL INVITE ******************/

static pj_bool_t on_rx_request(pjsip_rx_data *rdata)
{
    if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG &&
	rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD)
    {
	pjsip_dialog *dlg;
	pjmedia_sdp_session *sdp = NULL;
	pj_str_t uri;
	pjsip_tx_data *tdata;
	pj_status_t status;

	/*
	 * Create UAS
	 */
	uri = pj_str(CONTACT);
	status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata,
				      &uri, &dlg);
	pj_assert(status == PJ_SUCCESS);

	if (inv_test.param.oa[0] == OFFERER_UAC)
	    sdp = create_sdp(rdata->tp_info.pool, oa_sdp[0].answer);
	else if (inv_test.param.oa[0] == OFFERER_UAS)
	    sdp = create_sdp(rdata->tp_info.pool, oa_sdp[0].offer);
	else
	    pj_assert(!"Invalid offerer type");

	status = pjsip_inv_create_uas(dlg, rdata, sdp, inv_test.param.inv_option, &inv_test.uas);
	pj_assert(status == PJ_SUCCESS);

	TRACE_((THIS_FILE, "    Sending 183 with SDP"));

	/*
	 * Answer with 183
	 */
	status = pjsip_inv_initial_answer(inv_test.uas, rdata, 183, NULL,
					  NULL, &tdata);
	pj_assert(status == PJ_SUCCESS);

	status = pjsip_inv_send_msg(inv_test.uas, tdata);
	pj_assert(status == PJ_SUCCESS);

	return PJ_TRUE;
    }

    return PJ_FALSE;
}

static pjsip_module mod_inv_oa_test =
{
    NULL, NULL,			    /* prev, next.		*/
    { "mod-inv-oa-test", 15 },	    /* Name.			*/
    -1,				    /* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority			*/
    NULL,			    /* load()			*/
    NULL,			    /* start()			*/
    NULL,			    /* stop()			*/
    NULL,			    /* unload()			*/
    &on_rx_request,		    /* on_rx_request()		*/
    NULL,			    /* on_rx_response()		*/
    NULL,			    /* on_tx_request.		*/
    NULL,			    /* on_tx_response()		*/
    NULL,			    /* on_tsx_state()		*/
};


/**************** THE TEST ******************/
static void run_job(job_t *j)
{
    pjsip_inv_session *inv;
    pjsip_tx_data *tdata;
    pjmedia_sdp_session *sdp;
    pj_status_t status;

    if (j->who == PJSIP_ROLE_UAC)
	inv = inv_test.uac;
    else
	inv = inv_test.uas;

    switch (j->type) {
    case SEND_OFFER:
	sdp = create_sdp(inv->dlg->pool, oa_sdp[inv_test.oa_index].offer);

	TRACE_((THIS_FILE, "    Sending UPDATE with offer"));
	status = pjsip_inv_update(inv, NULL, sdp, &tdata);
	pj_assert(status == PJ_SUCCESS);

	status = pjsip_inv_send_msg(inv, tdata);
	pj_assert(status == PJ_SUCCESS);
	break;
    case ESTABLISH_CALL:
	TRACE_((THIS_FILE, "    Sending 200/OK"));
	status = pjsip_inv_answer(inv, 200, NULL, NULL, &tdata);
	pj_assert(status == PJ_SUCCESS);

	status = pjsip_inv_send_msg(inv, tdata);
	pj_assert(status == PJ_SUCCESS);
	break;
    }
}


static int perform_test(inv_test_param_t *param)
{
    pj_str_t uri;
    pjsip_dialog *dlg;
    pjmedia_sdp_session *sdp;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_LOG(3,(THIS_FILE, "  %s", param->title));

    pj_bzero(&inv_test, sizeof(inv_test));
    pj_memcpy(&inv_test.param, param, sizeof(*param));
    job_cnt = 0;

    uri = pj_str(CONTACT);

    /*  
     * Create UAC
     */
    status = pjsip_dlg_create_uac(pjsip_ua_instance(), 
				  &uri, &uri, &uri, &uri, &dlg);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -10);

    if (inv_test.param.oa[0] == OFFERER_UAC)
	sdp = create_sdp(dlg->pool, oa_sdp[0].offer);
    else
	sdp = NULL;

    status = pjsip_inv_create_uac(dlg, sdp, inv_test.param.inv_option, &inv_test.uac);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -20);

    TRACE_((THIS_FILE, "    Sending INVITE %s offer", (sdp ? "with" : "without")));

    /*
     * Make call!
     */
    status = pjsip_inv_invite(inv_test.uac, &tdata);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);

    status = pjsip_inv_send_msg(inv_test.uac, tdata);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);

    /*
     * Wait until test completes
     */
    while (!inv_test.complete) {
	pj_time_val delay = {0, 20};

	pjsip_endpt_handle_events(endpt, &delay);

	while (job_cnt) {
	    job_t j;

	    j = jobs[0];
	    pj_array_erase(jobs, sizeof(jobs[0]), job_cnt, 0);
	    --job_cnt;

	    run_job(&j);
	}
    }

    flush_events(100);

    /*
     * Hangup
     */
    TRACE_((THIS_FILE, "    Disconnecting call"));
    status = pjsip_inv_end_session(inv_test.uas, PJSIP_SC_DECLINE, 0, &tdata);
    pj_assert(status == PJ_SUCCESS);

    status = pjsip_inv_send_msg(inv_test.uas, tdata);
    pj_assert(status == PJ_SUCCESS);

    flush_events(500);

    return 0;
}


static pj_bool_t log_on_rx_msg(pjsip_rx_data *rdata)
{
    pjsip_msg *msg = rdata->msg_info.msg;
    char info[80];

    if (msg->type == PJSIP_REQUEST_MSG)
	pj_ansi_snprintf(info, sizeof(info), "%.*s", 
	    (int)msg->line.req.method.name.slen,
	    msg->line.req.method.name.ptr);
    else
	pj_ansi_snprintf(info, sizeof(info), "%d/%.*s",
	    msg->line.status.code,
	    (int)rdata->msg_info.cseq->method.name.slen,
	    rdata->msg_info.cseq->method.name.ptr);

    TRACE_((THIS_FILE, "      Received %s %s sdp", info,
	(msg->body ? "with" : "without")));

    return PJ_FALSE;
}


/* Message logger module. */
static pjsip_module mod_msg_logger = 
{
    NULL, NULL,				/* prev and next	*/
    { "mod-msg-loggee", 14},		/* Name.		*/
    -1,					/* Id			*/
    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority		*/
    NULL,				/* load()		*/
    NULL,				/* start()		*/
    NULL,				/* stop()		*/
    NULL,				/* unload()		*/
    &log_on_rx_msg,			/* on_rx_request()	*/
    &log_on_rx_msg,			/* on_rx_response()	*/
    NULL,				/* on_tx_request()	*/
    NULL,				/* on_tx_response()	*/
    NULL,				/* on_tsx_state()	*/
};

static inv_test_param_t test_params[] =
{
/* Normal scenario:

				UAC		UAS
    INVITE (offer)	-->
    200/INVITE (answer)	<--
    ACK    		-->
 */
#if 0
    {
	"Standard INVITE with offer",
	0,
	PJ_TRUE,
	1,
	{ OFFERER_UAC }
    },

    {
	"Standard INVITE with offer, with 100rel",
	PJSIP_INV_REQUIRE_100REL,
	PJ_TRUE,
	1,
	{ OFFERER_UAC }
    },
#endif

/* Delayed offer:
				UAC		UAS
    INVITE (no SDP) 	-->
    200/INVITE (offer) 	<--
    ACK (answer)   	-->
 */
#if 1
    {
	"INVITE with no offer",
	0,
	PJ_TRUE,
	1,
	{ OFFERER_UAS }
    },

    {
	"INVITE with no offer, with 100rel",
	PJSIP_INV_REQUIRE_100REL,
	PJ_TRUE,
	1,
	{ OFFERER_UAS }
    },
#endif

/* Subsequent UAC offer with UPDATE:

				UAC		UAS
    INVITE (offer)	-->
    180/rel (answer)	<--
    UPDATE (offer)	-->	inv_update()	on_rx_offer()
						set_sdp_answer()
    200/UPDATE (answer)	<--
    200/INVITE		<--
    ACK	-->
*/
#if 1
    {
	"INVITE and UPDATE by UAC",
	0,
	PJ_TRUE,
	2,
	{ OFFERER_UAC, OFFERER_UAC }
    },
    {
	"INVITE and UPDATE by UAC, with 100rel",
	PJSIP_INV_REQUIRE_100REL,
	PJ_TRUE,
	2,
	{ OFFERER_UAC, OFFERER_UAC }
    },
#endif

/* Subsequent UAS offer with UPDATE:

    INVITE (offer	-->
    180/rel (answer)	<--
    UPDATE (offer)	<--			inv_update()
				on_rx_offer()
				set_sdp_answer()
    200/UPDATE (answer) -->
    UPDATE (offer)	-->			on_rx_offer()
						set_sdp_answer()
    200/UPDATE (answer) <--
    200/INVITE		<--
    ACK			-->

 */
    {
	"INVITE and many UPDATE by UAC and UAS",
	0,
	PJ_TRUE,
	4,
	{ OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS }
    },

};


static pjsip_dialog* on_dlg_forked(pjsip_dialog *first_set, pjsip_rx_data *res)
{
    PJ_UNUSED_ARG(first_set);
    PJ_UNUSED_ARG(res);

    return NULL;
}


static void on_new_session(pjsip_inv_session *inv, pjsip_event *e)
{
    PJ_UNUSED_ARG(inv);
    PJ_UNUSED_ARG(e);
}


int inv_offer_answer_test(void)
{
    unsigned i;
    int rc = 0;

    /* Init UA layer */
    if (pjsip_ua_instance()->id == -1) {
	pjsip_ua_init_param ua_param;
	pj_bzero(&ua_param, sizeof(ua_param));
	ua_param.on_dlg_forked = &on_dlg_forked;
	pjsip_ua_init_module(endpt, &ua_param);
    }

    /* Init inv-usage */
    if (pjsip_inv_usage_instance()->id == -1) {
	pjsip_inv_callback inv_cb;
	pj_bzero(&inv_cb, sizeof(inv_cb));
	inv_cb.on_media_update = &on_media_update;
	inv_cb.on_rx_offer = &on_rx_offer;
	inv_cb.on_create_offer = &on_create_offer;
	inv_cb.on_state_changed = &on_state_changed;
	inv_cb.on_new_session = &on_new_session;
	pjsip_inv_usage_init(endpt, &inv_cb);
    }

    /* 100rel module */
    pjsip_100rel_init_module(endpt);

    /* Our module */
    pjsip_endpt_register_module(endpt, &mod_inv_oa_test);
    pjsip_endpt_register_module(endpt, &mod_msg_logger);

    /* Create SIP UDP transport */
    {
	pj_sockaddr_in addr;
	pjsip_transport *tp;
	pj_status_t status;

	pj_sockaddr_in_init(&addr, NULL, PORT);
	status = pjsip_udp_transport_start(endpt, &addr, NULL, 1, &tp);
	pj_assert(status == PJ_SUCCESS);
    }

    /* Do tests */
    for (i=0; i<PJ_ARRAY_SIZE(test_params); ++i) {
	rc = perform_test(&test_params[i]);
	if (rc != 0)
	    goto on_return;
    }


on_return:
    return rc;
}

