/* $Id$ */
/* 
 * Copyright (C) 2008-2009 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 <pjsip-ua/sip_xfer.h>
#include <pjsip-simple/evsub_msg.h>
#include <pjsip/sip_dialog.h>
#include <pjsip/sip_errno.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_transport.h>
#include <pj/assert.h>
#include <pj/pool.h>
#include <pj/string.h>


/*
 * Refer module (mod-refer)
 */
static struct pjsip_module mod_xfer = 
{
    NULL, NULL,				/* prev, next.			*/
    { "mod-refer", 9 },			/* Name.			*/
    -1,					/* Id				*/
    PJSIP_MOD_PRIORITY_DIALOG_USAGE,	/* Priority			*/
    NULL,				/* load()			*/
    NULL,				/* start()			*/
    NULL,				/* stop()			*/
    NULL,				/* unload()			*/
    NULL,				/* on_rx_request()		*/
    NULL,				/* on_rx_response()		*/
    NULL,				/* on_tx_request.		*/
    NULL,				/* on_tx_response()		*/
    NULL,				/* on_tsx_state()		*/
};


/* Declare PJSIP_REFER_METHOD, so that if somebody declares this in
 * sip_msg.h we can catch the error here.
 */
enum
{
    PJSIP_REFER_METHOD = PJSIP_OTHER_METHOD
};

PJ_DEF_DATA(const pjsip_method) pjsip_refer_method = {
    (pjsip_method_e) PJSIP_REFER_METHOD,
    { "REFER", 5}
};

PJ_DEF(const pjsip_method*) pjsip_get_refer_method()
{
    return &pjsip_refer_method;
}

/*
 * String constants
 */
const pj_str_t STR_REFER = { "refer", 5 };
const pj_str_t STR_MESSAGE = { "message", 7 };
const pj_str_t STR_SIPFRAG = { "sipfrag", 7 };
const pj_str_t STR_SIPFRAG_VERSION = {";version=2.0", 12 };


/*
 * Transfer struct.
 */
struct pjsip_xfer
{
    pjsip_evsub		*sub;		/**< Event subscribtion record.	    */
    pjsip_dialog	*dlg;		/**< The dialog.		    */
    pjsip_evsub_user	 user_cb;	/**< The user callback.		    */
    pj_str_t		 refer_to_uri;	/**< The full Refer-To URI.	    */
    int			 last_st_code;	/**< st_code sent in last NOTIFY    */
    pj_str_t		 last_st_text;	/**< st_text sent in last NOTIFY    */
};


typedef struct pjsip_xfer pjsip_xfer;



/*
 * Forward decl for evsub callback.
 */
static void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
static void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				     pjsip_event *event);
static void xfer_on_evsub_rx_refresh( pjsip_evsub *sub, 
				      pjsip_rx_data *rdata,
				      int *p_st_code,
				      pj_str_t **p_st_text,
				      pjsip_hdr *res_hdr,
				      pjsip_msg_body **p_body);
static void xfer_on_evsub_rx_notify( pjsip_evsub *sub, 
				     pjsip_rx_data *rdata,
				     int *p_st_code,
				     pj_str_t **p_st_text,
				     pjsip_hdr *res_hdr,
				     pjsip_msg_body **p_body);
static void xfer_on_evsub_client_refresh(pjsip_evsub *sub);
static void xfer_on_evsub_server_timeout(pjsip_evsub *sub);


/*
 * Event subscription callback for xference.
 */
static pjsip_evsub_user xfer_user = 
{
    &xfer_on_evsub_state,
    &xfer_on_evsub_tsx_state,
    &xfer_on_evsub_rx_refresh,
    &xfer_on_evsub_rx_notify,
    &xfer_on_evsub_client_refresh,
    &xfer_on_evsub_server_timeout,
};




/*
 * Initialize the REFER subsystem.
 */
PJ_DEF(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt)
{
    const pj_str_t accept = { "message/sipfrag;version=2.0", 27 };
    pj_status_t status;

    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);
    PJ_ASSERT_RETURN(mod_xfer.id == -1, PJ_EINVALIDOP);

    status = pjsip_endpt_register_module(endpt, &mod_xfer);
    if (status != PJ_SUCCESS)
	return status;

    status = pjsip_endpt_add_capability( endpt, &mod_xfer, PJSIP_H_ALLOW, 
					 NULL, 1, 
					 &pjsip_get_refer_method()->name);
    if (status != PJ_SUCCESS)
	return status;

    status = pjsip_evsub_register_pkg( &mod_xfer, &STR_REFER, 300, 1, &accept);
    if (status != PJ_SUCCESS)
	return status;

    return PJ_SUCCESS;
}


/*
 * Create transferer (sender of REFER request).
 *
 */
PJ_DEF(pj_status_t) pjsip_xfer_create_uac( pjsip_dialog *dlg,
					   const pjsip_evsub_user *user_cb,
					   pjsip_evsub **p_evsub )
{
    pj_status_t status;
    pjsip_xfer *xfer;
    pjsip_evsub *sub;

    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);

    pjsip_dlg_inc_lock(dlg);

    /* Create event subscription */
    status = pjsip_evsub_create_uac( dlg,  &xfer_user, &STR_REFER, 
				     PJSIP_EVSUB_NO_EVENT_ID, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create xfer session */
    xfer = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_xfer);
    xfer->dlg = dlg;
    xfer->sub = sub;
    if (user_cb)
	pj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);

    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;

}




/*
 * Create transferee (receiver of REFER request).
 *
 */
PJ_DEF(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,
					   const pjsip_evsub_user *user_cb,
					   pjsip_rx_data *rdata,
					   pjsip_evsub **p_evsub )
{
    pjsip_evsub *sub;
    pjsip_xfer *xfer;
    const pj_str_t STR_EVENT = {"Event", 5 };
    pjsip_event_hdr *event_hdr;
    pj_status_t status;

    /* Check arguments */
    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);

    /* Must be request message */
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
		     PJSIP_ENOTREQUESTMSG);

    /* Check that request is REFER */
    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
				      pjsip_get_refer_method())==0,
		     PJSIP_ENOTREFER);

    /* Lock dialog */
    pjsip_dlg_inc_lock(dlg);

    /* The evsub framework expects an Event header in the request,
     * while a REFER request conveniently doesn't have one (pun intended!).
     * So create a dummy Event header.
     */
    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
				   &STR_EVENT, NULL)==NULL)
    {
	event_hdr = pjsip_event_hdr_create(rdata->tp_info.pool);
	event_hdr->event_type = STR_REFER;
	pjsip_msg_add_hdr(rdata->msg_info.msg, (pjsip_hdr*)event_hdr);
    }

    /* Create server subscription */
    status = pjsip_evsub_create_uas( dlg, &xfer_user, rdata, 
				     PJSIP_EVSUB_NO_EVENT_ID, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Create server xfer subscription */
    xfer = PJ_POOL_ZALLOC_T(dlg->pool, pjsip_xfer);
    xfer->dlg = dlg;
    xfer->sub = sub;
    if (user_cb)
	pj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);

    /* Done: */
    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}



/*
 * Call this function to create request to initiate REFER subscription.
 *
 */
PJ_DEF(pj_status_t) pjsip_xfer_initiate( pjsip_evsub *sub,
					 const pj_str_t *refer_to_uri,
					 pjsip_tx_data **p_tdata)
{
    pjsip_xfer *xfer;
    const pj_str_t refer_to = { "Refer-To", 8};
    pjsip_tx_data *tdata;
    pjsip_generic_string_hdr *hdr;
    pj_status_t status;

    /* sub and p_tdata argument must be valid.  */
    PJ_ASSERT_RETURN(sub && p_tdata, PJ_EINVAL);


    /* Get the xfer object. */
    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);

    /* refer_to_uri argument MAY be NULL for subsequent REFER requests,
     * but it MUST be specified in the first REFER.
     */
    PJ_ASSERT_RETURN((refer_to_uri || xfer->refer_to_uri.slen), PJ_EINVAL);

    /* Lock dialog. */
    pjsip_dlg_inc_lock(xfer->dlg);

    /* Create basic REFER request */
    status = pjsip_evsub_initiate(sub, pjsip_get_refer_method(), -1, 
				  &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Save Refer-To URI. */
    if (refer_to_uri == NULL) {
	refer_to_uri = &xfer->refer_to_uri;
    } else {
	pj_strdup(xfer->dlg->pool, &xfer->refer_to_uri, refer_to_uri);
    }

    /* Create and add Refer-To header. */
    hdr = pjsip_generic_string_hdr_create(tdata->pool, &refer_to,
					  refer_to_uri);
    if (!hdr) {
	pjsip_tx_data_dec_ref(tdata);
	status = PJ_ENOMEM;
	goto on_return;
    }

    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);


    /* Done. */
    *p_tdata = tdata;

    status = PJ_SUCCESS;

on_return:
    pjsip_dlg_dec_lock(xfer->dlg);
    return status;
}


/*
 * Accept the incoming REFER request by sending 2xx response.
 *
 */
PJ_DEF(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub,
				       pjsip_rx_data *rdata,
				       int st_code,
				       const pjsip_hdr *hdr_list )
{
    /*
     * Don't need to add custom headers, so just call basic
     * evsub response.
     */
    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );
}


/*
 * For notifier, create NOTIFY request to subscriber, and set the state 
 * of the subscription. 
 */
PJ_DEF(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,
				       pjsip_evsub_state state,
				       int xfer_st_code,
				       const pj_str_t *xfer_st_text,
				       pjsip_tx_data **p_tdata)
{
    pjsip_tx_data *tdata;
    pjsip_xfer *xfer;
    const pj_str_t reason = { "noresource", 10 };
    char *body;
    int bodylen;
    pjsip_msg_body *msg_body;
    pj_status_t status;
    

    /* Check arguments. */
    PJ_ASSERT_RETURN(sub, PJ_EINVAL);

    /* Get the xfer object. */
    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);


    /* Lock object. */
    pjsip_dlg_inc_lock(xfer->dlg);

    /* Create the NOTIFY request. 
     * Note that reason is only used when state is TERMINATED, and
     * the defined termination reason for REFER is "noresource".
     */
    status = pjsip_evsub_notify( sub, state, NULL, &reason, &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;


    /* Check status text */
    if (xfer_st_text==NULL || xfer_st_text->slen==0)
	xfer_st_text = pjsip_get_status_text(xfer_st_code);

    /* Save st_code and st_text, for current_notify() */
    xfer->last_st_code = xfer_st_code;
    pj_strdup(xfer->dlg->pool, &xfer->last_st_text, xfer_st_text);

    /* Create sipfrag content. */
    body = (char*) pj_pool_alloc(tdata->pool, 128);
    bodylen = pj_ansi_snprintf(body, 128, "SIP/2.0 %u %.*s\r\n",
			       xfer_st_code,
			       (int)xfer_st_text->slen,
			       xfer_st_text->ptr);
    PJ_ASSERT_ON_FAIL(bodylen > 0 && bodylen < 128, 
			{status=PJ_EBUG; pjsip_tx_data_dec_ref(tdata); 
			 goto on_return; });


    /* Create SIP message body. */
    msg_body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);
    msg_body->content_type.type = STR_MESSAGE;
    msg_body->content_type.subtype = STR_SIPFRAG;
    msg_body->content_type.param = STR_SIPFRAG_VERSION;
    msg_body->data = body;
    msg_body->len = bodylen;
    msg_body->print_body = &pjsip_print_text_body;
    msg_body->clone_data = &pjsip_clone_text_data;

    /* Attach sipfrag body. */
    tdata->msg->body = msg_body;


    /* Done. */
    *p_tdata = tdata;


on_return:
    pjsip_dlg_dec_lock(xfer->dlg);
    return status;

}


/*
 * Send current state and the last sipfrag body.
 */
PJ_DEF(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub,
					       pjsip_tx_data **p_tdata )
{
    pjsip_xfer *xfer;
    pj_status_t status;
    

    /* Check arguments. */
    PJ_ASSERT_RETURN(sub, PJ_EINVAL);

    /* Get the xfer object. */
    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);

    pjsip_dlg_inc_lock(xfer->dlg);

    status = pjsip_xfer_notify(sub, pjsip_evsub_get_state(sub),
			       xfer->last_st_code, &xfer->last_st_text,
			       p_tdata);

    pjsip_dlg_dec_lock(xfer->dlg);

    return status;
}


/*
 * Send request message. 
 */
PJ_DEF(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub,
					     pjsip_tx_data *tdata)
{
    return pjsip_evsub_send_request(sub, tdata);
}


/*
 * This callback is called by event subscription when subscription
 * state has changed.
 */
static void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
{
    pjsip_xfer *xfer;

    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});

    if (xfer->user_cb.on_evsub_state)
	(*xfer->user_cb.on_evsub_state)(sub, event);

}

/*
 * Called when transaction state has changed.
 */
static void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				     pjsip_event *event)
{
    pjsip_xfer *xfer;

    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});

    if (xfer->user_cb.on_tsx_state)
	(*xfer->user_cb.on_tsx_state)(sub, tsx, event);
}

/*
 * Called when REFER is received to refresh subscription.
 */
static void xfer_on_evsub_rx_refresh( pjsip_evsub *sub, 
				      pjsip_rx_data *rdata,
				      int *p_st_code,
				      pj_str_t **p_st_text,
				      pjsip_hdr *res_hdr,
				      pjsip_msg_body **p_body)
{
    pjsip_xfer *xfer;

    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});

    if (xfer->user_cb.on_rx_refresh) {
	(*xfer->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text,
				       res_hdr, p_body);

    } else {
	/* Implementors MUST send NOTIFY if it implements on_rx_refresh
	 * (implementor == "us" from evsub point of view.
	 */
	pjsip_tx_data *tdata;
	pj_status_t status;

	if (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {
	    status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,
					xfer->last_st_code,
					&xfer->last_st_text, 
					&tdata);
	} else {
	    status = pjsip_xfer_current_notify(sub, &tdata);
	}

	if (status == PJ_SUCCESS)
	    pjsip_xfer_send_request(sub, tdata);
    }
}


/*
 * Called when NOTIFY is received.
 */
static void xfer_on_evsub_rx_notify( pjsip_evsub *sub, 
				     pjsip_rx_data *rdata,
				     int *p_st_code,
				     pj_str_t **p_st_text,
				     pjsip_hdr *res_hdr,
				     pjsip_msg_body **p_body)
{
    pjsip_xfer *xfer;

    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});

    if (xfer->user_cb.on_rx_notify)
	(*xfer->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text,
				      res_hdr, p_body);
}

/*
 * Called when it's time to send SUBSCRIBE.
 */
static void xfer_on_evsub_client_refresh(pjsip_evsub *sub)
{
    pjsip_xfer *xfer;

    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});

    if (xfer->user_cb.on_client_refresh) {
	(*xfer->user_cb.on_client_refresh)(sub);
    } else {
	pj_status_t status;
	pjsip_tx_data *tdata;

	status = pjsip_xfer_initiate(sub, NULL, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_xfer_send_request(sub, tdata);
    }
}


/*
 * Called when no refresh is received after the interval.
 */
static void xfer_on_evsub_server_timeout(pjsip_evsub *sub)
{
    pjsip_xfer *xfer;

    xfer = (pjsip_xfer*) pjsip_evsub_get_mod_data(sub, mod_xfer.id);
    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});

    if (xfer->user_cb.on_server_timeout) {
	(*xfer->user_cb.on_server_timeout)(sub);
    } else {
	pj_status_t status;
	pjsip_tx_data *tdata;

	status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
				   xfer->last_st_code, 
				   &xfer->last_st_text, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_xfer_send_request(sub, tdata);
    }
}

