/* $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 <pjsip-simple/mwi.h>
#include <pjsip-simple/errno.h>
#include <pjsip-simple/evsub_msg.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_dialog.h>
#include <pj/assert.h>
#include <pj/guid.h>
#include <pj/log.h>
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/string.h>


#define THIS_FILE		    "mwi.c"

 /*
 * MWI module (mod-mdi)
 */
static struct pjsip_module mod_mwi = 
{
    NULL, NULL,			    /* prev, next.			*/
    { "mod-mwi", 7 },		    /* 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()			*/
};


/*
 * This structure describe an mwi agent (both client and server)
 */
typedef struct pjsip_mwi
{
    pjsip_evsub		*sub;		/**< Event subscribtion record.	    */
    pjsip_dialog	*dlg;		/**< The dialog.		    */
    pjsip_evsub_user	 user_cb;	/**< The user callback.		    */

    /* These are for server subscriptions */
    pj_pool_t		*body_pool;	/**< Pool to save message body	    */
    pjsip_media_type	 mime_type;	/**< MIME type of last msg body	    */
    pj_str_t		 body;		/**< Last sent message body	    */
} pjsip_mwi;


/*
 * Forward decl for evsub callbacks.
 */
static void mwi_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
static void mwi_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				    pjsip_event *event);
static void mwi_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 mwi_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 mwi_on_evsub_client_refresh(pjsip_evsub *sub);
static void mwi_on_evsub_server_timeout(pjsip_evsub *sub);


/*
 * Event subscription callback for mwi.
 */
static pjsip_evsub_user mwi_user = 
{
    &mwi_on_evsub_state,
    &mwi_on_evsub_tsx_state,
    &mwi_on_evsub_rx_refresh,
    &mwi_on_evsub_rx_notify,
    &mwi_on_evsub_client_refresh,
    &mwi_on_evsub_server_timeout,
};


/*
 * Some static constants.
 */
static const pj_str_t STR_EVENT		 = { "Event", 5 };
static const pj_str_t STR_MWI		 = { "message-summary", 15 };
static const pj_str_t STR_APP_SIMPLE_SMS = { "application/simple-message-summary", 34};

/*
 * Init mwi module.
 */
PJ_DEF(pj_status_t) pjsip_mwi_init_module( pjsip_endpoint *endpt,
					   pjsip_module *mod_evsub)
{
    pj_status_t status;
    pj_str_t accept[1];

    /* Check arguments. */
    PJ_ASSERT_RETURN(endpt && mod_evsub, PJ_EINVAL);

    /* Must have not been registered */
    PJ_ASSERT_RETURN(mod_mwi.id == -1, PJ_EINVALIDOP);

    /* Register to endpoint */
    status = pjsip_endpt_register_module(endpt, &mod_mwi);
    if (status != PJ_SUCCESS)
	return status;

    accept[0] = STR_APP_SIMPLE_SMS;

    /* Register event package to event module. */
    status = pjsip_evsub_register_pkg( &mod_mwi, &STR_MWI, 
				       PJSIP_MWI_DEFAULT_EXPIRES, 
				       PJ_ARRAY_SIZE(accept), accept);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_unregister_module(endpt, &mod_mwi);
	return status;
    }

    return PJ_SUCCESS;
}


/*
 * Get mwi module instance.
 */
PJ_DEF(pjsip_module*) pjsip_mwi_instance(void)
{
    return &mod_mwi;
}


/*
 * Create client subscription.
 */
PJ_DEF(pj_status_t) pjsip_mwi_create_uac( pjsip_dialog *dlg,
					  const pjsip_evsub_user *user_cb,
					  unsigned options,
					  pjsip_evsub **p_evsub )
{
    pj_status_t status;
    pjsip_mwi *mwi;
    pjsip_evsub *sub;

    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);

    PJ_UNUSED_ARG(options);

    pjsip_dlg_inc_lock(dlg);

    /* Create event subscription */
    status = pjsip_evsub_create_uac( dlg,  &mwi_user, &STR_MWI, 
				     options, &sub);
    if (status != PJ_SUCCESS)
	goto on_return;

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

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_mwi.id, mwi);

    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Create server subscription.
 */
PJ_DEF(pj_status_t) pjsip_mwi_create_uas( pjsip_dialog *dlg,
					  const pjsip_evsub_user *user_cb,
					  pjsip_rx_data *rdata,
					  pjsip_evsub **p_evsub )
{
    pjsip_accept_hdr *accept;
    pjsip_event_hdr *event;
    pjsip_evsub *sub;
    pjsip_mwi *mwi;
    char obj_name[PJ_MAX_OBJ_NAME];
    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 SUBSCRIBE */
    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
				      &pjsip_subscribe_method)==0,
		     PJSIP_SIMPLE_ENOTSUBSCRIBE);

    /* Check that Event header contains "mwi" */
    event = (pjsip_event_hdr*)
    	    pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_EVENT, NULL);
    if (!event) {
	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
    }
    if (pj_stricmp(&event->event_type, &STR_MWI) != 0) {
	return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EVENT);
    }

    /* Check that request contains compatible Accept header. */
    accept = (pjsip_accept_hdr*)
    	     pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);
    if (accept) {
	unsigned i;
	for (i=0; i<accept->count; ++i) {
	    if (pj_stricmp(&accept->values[i], &STR_APP_SIMPLE_SMS)==0) {
		break;
	    }
	}

	if (i==accept->count) {
	    /* Nothing is acceptable */
	    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
	}

    } else {
	/* No Accept header. 
	 * Assume client supports "application/simple-message-summary" 
	*/
    }

    /* Lock dialog */
    pjsip_dlg_inc_lock(dlg);


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

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

    pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "mwibd%p", dlg->pool);
    mwi->body_pool = pj_pool_create(dlg->pool->factory, obj_name, 
				    512, 512, NULL);

    /* Attach to evsub */
    pjsip_evsub_set_mod_data(sub, mod_mwi.id, mwi);

    /* Done: */
    *p_evsub = sub;

on_return:
    pjsip_dlg_dec_lock(dlg);
    return status;
}


/*
 * Forcefully terminate mwi.
 */
PJ_DEF(pj_status_t) pjsip_mwi_terminate( pjsip_evsub *sub,
					 pj_bool_t notify )
{
    return pjsip_evsub_terminate(sub, notify);
}

/*
 * Create SUBSCRIBE
 */
PJ_DEF(pj_status_t) pjsip_mwi_initiate( pjsip_evsub *sub,
					pj_int32_t expires,
					pjsip_tx_data **p_tdata)
{
    return pjsip_evsub_initiate(sub, &pjsip_subscribe_method, expires, 
				p_tdata);
}


/*
 * Accept incoming subscription.
 */
PJ_DEF(pj_status_t) pjsip_mwi_accept( pjsip_evsub *sub,
				      pjsip_rx_data *rdata,
				      int st_code,
				      const pjsip_hdr *hdr_list )
{
    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );
}

/*
 * Create message body and attach it to the (NOTIFY) request.
 */
static pj_status_t mwi_create_msg_body( pjsip_mwi *mwi, 
					pjsip_tx_data *tdata)
{
    pjsip_msg_body *body;
    pj_str_t dup_text;

    PJ_ASSERT_RETURN(mwi->mime_type.type.slen && mwi->body.slen, PJ_EINVALIDOP);
    
    /* Clone the message body and mime type */
    pj_strdup(tdata->pool, &dup_text, &mwi->body);

    /* Create the message body */
    body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);
    pjsip_media_type_cp(tdata->pool, &body->content_type, &mwi->mime_type);
    body->data = dup_text.ptr;
    body->len = (unsigned)dup_text.slen;
    body->print_body = &pjsip_print_text_body;
    body->clone_data = &pjsip_clone_text_data;

    /* Attach to tdata */
    tdata->msg->body = body;

    return PJ_SUCCESS;
}


/*
 * Create NOTIFY
 */
PJ_DEF(pj_status_t) pjsip_mwi_notify(  pjsip_evsub *sub,
				       pjsip_evsub_state state,
				       const pj_str_t *state_str,
				       const pj_str_t *reason,
				       const pjsip_media_type *mime_type,
				       const pj_str_t *body,
				       pjsip_tx_data **p_tdata)
{
    pjsip_mwi *mwi;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    /* Check arguments. */
    PJ_ASSERT_RETURN(sub && mime_type && body && p_tdata, PJ_EINVAL);

    /* Get the mwi object. */
    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_RETURN(mwi != NULL, PJ_EINVALIDOP);

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

    /* Create the NOTIFY request. */
    status = pjsip_evsub_notify( sub, state, state_str, reason, &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Update the cached message body */
    if (mime_type || body)
	pj_pool_reset(mwi->body_pool);
    if (mime_type)
	pjsip_media_type_cp(mwi->body_pool, &mwi->mime_type, mime_type);
    if (body)
	pj_strdup(mwi->body_pool, &mwi->body, body);

    /* Create message body */
    status = mwi_create_msg_body( mwi, tdata );
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Done. */
    *p_tdata = tdata;

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


/*
 * Create NOTIFY that reflect current state.
 */
PJ_DEF(pj_status_t) pjsip_mwi_current_notify( pjsip_evsub *sub,
					      pjsip_tx_data **p_tdata )
{
    pjsip_mwi *mwi;
    pjsip_tx_data *tdata;
    pj_status_t status;
    
    /* Check arguments. */
    PJ_ASSERT_RETURN(sub && p_tdata, PJ_EINVAL);

    /* Get the mwi object. */
    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_RETURN(mwi != NULL, PJ_EINVALIDOP);

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

    /* Create the NOTIFY request. */
    status = pjsip_evsub_current_notify( sub, &tdata);
    if (status != PJ_SUCCESS)
	goto on_return;


    /* Create message body to reflect the mwi status. */
    status = mwi_create_msg_body( mwi, tdata );
    if (status != PJ_SUCCESS)
	goto on_return;

    /* Done. */
    *p_tdata = tdata;

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


/*
 * Send request.
 */
PJ_DEF(pj_status_t) pjsip_mwi_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 mwi_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

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

    if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	if (mwi->body_pool) {
	    pj_pool_release(mwi->body_pool);
	    mwi->body_pool = NULL;
	}
    }
}

/*
 * Called when transaction state has changed.
 */
static void mwi_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,
				     pjsip_event *event)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

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


/*
 * Called when SUBSCRIBE is received.
 */
static void mwi_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_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_rx_refresh) {
	(*mwi->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 */
	pjsip_tx_data *tdata;
	pj_str_t timeout = { "timeout", 7};
	pj_status_t status;

	if (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {
	    status = pjsip_mwi_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,
				       NULL, &timeout, NULL, NULL, &tdata);
	} else {
	    status = pjsip_mwi_current_notify(sub, &tdata);
	}

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


/*
 * Called when NOTIFY is received.
 */
static void mwi_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_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    /* Just notify application. */
    if (mwi->user_cb.on_rx_notify) {
	(*mwi->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 mwi_on_evsub_client_refresh(pjsip_evsub *sub)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

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

	status = pjsip_mwi_initiate(sub, -1, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_mwi_send_request(sub, tdata);
    }
}

/*
 * Called when no refresh is received after the interval.
 */
static void mwi_on_evsub_server_timeout(pjsip_evsub *sub)
{
    pjsip_mwi *mwi;

    mwi = (pjsip_mwi*) pjsip_evsub_get_mod_data(sub, mod_mwi.id);
    PJ_ASSERT_ON_FAIL(mwi!=NULL, {return;});

    if (mwi->user_cb.on_server_timeout) {
	(*mwi->user_cb.on_server_timeout)(sub);
    } else {
	pj_status_t status;
	pjsip_tx_data *tdata;
	pj_str_t reason = { "timeout", 7 };

	status = pjsip_mwi_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
				   NULL, &reason, NULL, NULL, &tdata);
	if (status == PJ_SUCCESS)
	    pjsip_mwi_send_request(sub, tdata);
    }
}

