/* $Id$ */
/* 
 * Copyright (C) 2003-2006 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 "pjsua.h"

/*
 * pjsua_pres.c
 *
 * Presence related stuffs.
 */

#define THIS_FILE   "pjsua_pres.c"



/* **************************************************************************
 * THE FOLLOWING PART HANDLES SERVER SUBSCRIPTION
 * **************************************************************************
 */

/* Proto */
static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata);

/* The module instance. */
static pjsip_module mod_pjsua_pres = 
{
    NULL, NULL,				/* prev, next.		*/
    { "mod-pjsua-pres", 14 },		/* Name.		*/
    -1,					/* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION,	/* Priority	        */
    NULL,				/* User data.		*/
    NULL,				/* load()		*/
    NULL,				/* start()		*/
    NULL,				/* stop()		*/
    NULL,				/* unload()		*/
    &pres_on_rx_request,		/* on_rx_request()	*/
    NULL,				/* on_rx_response()	*/
    NULL,				/* on_tx_request.	*/
    NULL,				/* on_tx_response()	*/
    NULL,				/* on_tsx_state()	*/

};


/* Callback called when *server* subscription state has changed. */
static void pres_evsub_on_srv_state( pjsip_evsub *sub, pjsip_event *event)
{
    pjsua_srv_pres *uapres = pjsip_evsub_get_mod_data(sub, pjsua.mod.id);

    PJ_UNUSED_ARG(event);

    if (uapres) {
	PJ_LOG(3,(THIS_FILE, "Server subscription to %s is %s",
		  uapres->remote, pjsip_evsub_get_state_name(sub)));

	if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	    pjsip_evsub_set_mod_data(sub, pjsua.mod.id, NULL);
	    pj_list_erase(uapres);
	}
    }
}

/* This is called when request is received. 
 * We need to check for incoming SUBSCRIBE request.
 */
static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata)
{
    pjsip_method *req_method = &rdata->msg_info.msg->line.req.method;
    pjsua_srv_pres *uapres;
    pjsip_evsub *sub;
    pjsip_evsub_user pres_cb;
    pjsip_tx_data *tdata;
    pjsip_pres_status pres_status;
    pjsip_dialog *dlg;
    pj_status_t status;

    if (pjsip_method_cmp(req_method, &pjsip_subscribe_method) != 0)
	return PJ_FALSE;

    /* Incoming SUBSCRIBE: */

    /* Create UAS dialog: */
    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata, 
				   &pjsua.contact_uri, &dlg);
    if (status != PJ_SUCCESS) {
	pjsua_perror("Unable to create UAS dialog for subscription", status);
	return PJ_FALSE;
    }

    /* Init callback: */
    pj_memset(&pres_cb, 0, sizeof(pres_cb));
    pres_cb.on_evsub_state = &pres_evsub_on_srv_state;

    /* Create server presence subscription: */
    status = pjsip_pres_create_uas( dlg, &pres_cb, rdata, &sub);
    if (status != PJ_SUCCESS) {
	PJ_TODO(DESTROY_DIALOG);
	pjsua_perror("Unable to create server subscription", status);
	return PJ_FALSE;
    }

    /* Attach our data to the subscription: */
    uapres = pj_pool_alloc(dlg->pool, sizeof(pjsua_srv_pres));
    uapres->sub = sub;
    uapres->remote = pj_pool_alloc(dlg->pool, PJSIP_MAX_URL_SIZE);
    status = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, dlg->remote.info->uri,
			     uapres->remote, PJSIP_MAX_URL_SIZE);
    if (status < 1)
	pj_ansi_strcpy(uapres->remote, "<-- url is too long-->");
    else
	uapres->remote[status] = '\0';

    pjsip_evsub_set_mod_data(sub, pjsua.mod.id, uapres);

    /* Add server subscription to the list: */
    pj_list_push_back(&pjsua.pres_srv_list, uapres);


    /* Create and send 200 (OK) to the SUBSCRIBE request: */
    status = pjsip_pres_accept(sub, rdata, 200, NULL);
    if (status != PJ_SUCCESS) {
	pjsua_perror("Unable to accept presence subscription", status);
	pj_list_erase(uapres);
	return PJ_FALSE;
    }


    /* Set our online status: */
    pj_memset(&pres_status, 0, sizeof(pres_status));
    pres_status.info_cnt = 1;
    pres_status.info[0].basic_open = pjsua.online_status;
    //Both pjsua.local_uri and pjsua.contact_uri are enclosed in "<" and ">"
    //causing XML parsing to fail.
    //pres_status.info[0].contact = pjsua.local_uri;

    pjsip_pres_set_status(sub, &pres_status);

    /* Create and send the first NOTIFY to active subscription: */
    status = pjsip_pres_notify( sub, PJSIP_EVSUB_STATE_ACTIVE, NULL,
			        NULL, &tdata);
    if (status == PJ_SUCCESS)
	status = pjsip_pres_send_request( sub, tdata);

    if (status != PJ_SUCCESS) {
	pjsua_perror("Unable to create/send NOTIFY", status);
	pj_list_erase(uapres);
	return PJ_FALSE;
    }


    /* Done: */

    return PJ_TRUE;
}


/* Refresh subscription (e.g. when our online status has changed) */
static void refresh_server_subscription()
{
    pjsua_srv_pres *uapres;

    uapres = pjsua.pres_srv_list.next;

    while (uapres != &pjsua.pres_srv_list) {
	
	pjsip_pres_status pres_status;
	pjsip_tx_data *tdata;

	pjsip_pres_get_status(uapres->sub, &pres_status);
	if (pres_status.info[0].basic_open != pjsua.online_status) {
	    pres_status.info[0].basic_open = pjsua.online_status;
	    pjsip_pres_set_status(uapres->sub, &pres_status);

	    if (pjsua.quit_flag) {
		pj_str_t reason = { "noresource", 10 };
		if (pjsip_pres_notify(uapres->sub, 
				      PJSIP_EVSUB_STATE_TERMINATED, NULL,
				      &reason, &tdata)==PJ_SUCCESS)
		{
		    pjsip_pres_send_request(uapres->sub, tdata);
		}
	    } else {
		if (pjsip_pres_current_notify(uapres->sub, &tdata)==PJ_SUCCESS)
		    pjsip_pres_send_request(uapres->sub, tdata);
	    }
	}

	uapres = uapres->next;
    }
}



/* **************************************************************************
 * THE FOLLOWING PART HANDLES CLIENT SUBSCRIPTION
 * **************************************************************************
 */

/* Callback called when *client* subscription state has changed. */
static void pjsua_evsub_on_state( pjsip_evsub *sub, pjsip_event *event)
{
    pjsua_buddy *buddy;

    PJ_UNUSED_ARG(event);

    buddy = pjsip_evsub_get_mod_data(sub, pjsua.mod.id);
    if (buddy) {
	PJ_LOG(3,(THIS_FILE, 
		  "Presence subscription to %s is %s",
		  buddy->uri.ptr, 
		  pjsip_evsub_get_state_name(sub)));

	if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
	    buddy->sub = NULL;
	    buddy->status.info_cnt = 0;
	    pjsip_evsub_set_mod_data(sub, pjsua.mod.id, NULL);
	}
    }
}

/* Callback called when we receive NOTIFY */
static void pjsua_evsub_on_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)
{
    pjsua_buddy *buddy;

    buddy = pjsip_evsub_get_mod_data(sub, pjsua.mod.id);
    if (buddy) {
	/* Update our info. */
	pjsip_pres_get_status(sub, &buddy->status);

	if (buddy->status.info_cnt) {
	    PJ_LOG(3,(THIS_FILE, "%s is %s",
		      buddy->uri.ptr,
		      (buddy->status.info[0].basic_open?"online":"offline")));
	} else {
	    PJ_LOG(3,(THIS_FILE, "No presence info for %s",
		      buddy->uri.ptr));
	}
    }

    /* The default is to send 200 response to NOTIFY.
     * Just leave it there..
     */
    PJ_UNUSED_ARG(rdata);
    PJ_UNUSED_ARG(p_st_code);
    PJ_UNUSED_ARG(p_st_text);
    PJ_UNUSED_ARG(res_hdr);
    PJ_UNUSED_ARG(p_body);
}


/* Event subscription callback. */
static pjsip_evsub_user pres_callback = 
{
    &pjsua_evsub_on_state,  

    NULL,   /* on_tsx_state: don't care about transaction state. */

    NULL,   /* on_rx_refresh: don't care about SUBSCRIBE refresh, unless 
	     * we want to authenticate 
	     */

    &pjsua_evsub_on_rx_notify,

    NULL,   /* on_client_refresh: Use default behaviour, which is to 
	     * refresh client subscription. */

    NULL,   /* on_server_timeout: Use default behaviour, which is to send 
	     * NOTIFY to terminate. 
	     */
};


/* It does what it says.. */
static void subscribe_buddy_presence(unsigned index)
{
    pjsip_dialog *dlg;
    pjsip_tx_data *tdata;
    pj_status_t status;

    status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
				   &pjsua.local_uri,
				   &pjsua.contact_uri,
				   &pjsua.buddies[index].uri,
				   NULL, &dlg);
    if (status != PJ_SUCCESS) {
	pjsua_perror("Unable to create dialog", status);
	return;
    }

    status = pjsip_pres_create_uac( dlg, &pres_callback, 
				    &pjsua.buddies[index].sub);
    if (status != PJ_SUCCESS) {
	pjsua.buddies[index].sub = NULL;
	pjsua_perror("Unable to create presence client", status);
	return;
    }

    pjsip_evsub_set_mod_data(pjsua.buddies[index].sub, pjsua.mod.id,
			     &pjsua.buddies[index]);

    status = pjsip_pres_initiate(pjsua.buddies[index].sub, 60, &tdata);
    if (status != PJ_SUCCESS) {
	pjsua.buddies[index].sub = NULL;
	pjsua_perror("Unable to create initial SUBSCRIBE", status);
	return;
    }

    status = pjsip_pres_send_request(pjsua.buddies[index].sub, tdata);
    if (status != PJ_SUCCESS) {
	pjsua.buddies[index].sub = NULL;
	pjsua_perror("Unable to send initial SUBSCRIBE", status);
	return;
    }

    PJ_TODO(DESTROY_DIALOG_ON_ERROR);
}


/* It does what it says... */
static void unsubscribe_buddy_presence(unsigned index)
{
    pjsip_tx_data *tdata;
    pj_status_t status;

    if (pjsua.buddies[index].sub == NULL)
	return;

    if (pjsip_evsub_get_state(pjsua.buddies[index].sub) == 
	PJSIP_EVSUB_STATE_TERMINATED)
    {
	pjsua.buddies[index].sub = NULL;
	return;
    }

    status = pjsip_pres_initiate( pjsua.buddies[index].sub, 0, &tdata);
    if (status == PJ_SUCCESS)
	status = pjsip_pres_send_request( pjsua.buddies[index].sub, tdata );

    if (status == PJ_SUCCESS) {

	//pjsip_evsub_set_mod_data(pjsua.buddies[index].sub, pjsua.mod.id,
	//				 NULL);
	//pjsua.buddies[index].sub = NULL;

    } else {
	pjsua_perror("Unable to unsubscribe presence", status);
    }
}


/* It does what it says.. */
static void refresh_client_subscription(void)
{
    unsigned i;

    for (i=0; i<pjsua.buddy_cnt; ++i) {

	if (pjsua.buddies[i].monitor && !pjsua.buddies[i].sub) {
	    subscribe_buddy_presence(i);

	} else if (!pjsua.buddies[i].monitor && pjsua.buddies[i].sub) {
	    unsubscribe_buddy_presence(i);

	}
    }
}


/*
 * Init presence
 */
pj_status_t pjsua_pres_init()
{
    pj_status_t status;

    status = pjsip_endpt_register_module( pjsua.endpt, &mod_pjsua_pres);
    if (status != PJ_SUCCESS) {
	pjsua_perror("Unable to register pjsua presence module", status);
    }

    return status;
}

/*
 * Refresh presence
 */
void pjsua_pres_refresh(void)
{
    refresh_client_subscription();
    refresh_server_subscription();
}


/*
 * Shutdown presence.
 */
void pjsua_pres_shutdown(void)
{
    unsigned i;

    pjsua.online_status = 0;
    for (i=0; i<pjsua.buddy_cnt; ++i) {
	pjsua.buddies[i].monitor = 0;
    }
    pjsua_pres_refresh();
}

/*
 * Dump presence status.
 */
void pjsua_pres_dump(void)
{
    unsigned i;

    PJ_LOG(3,(THIS_FILE, "Dumping pjsua server subscriptions:"));
    if (pj_list_empty(&pjsua.pres_srv_list)) {
	PJ_LOG(3,(THIS_FILE, "  - none - "));
    } else {
	struct pjsua_srv_pres *uapres;

	uapres = pjsua.pres_srv_list.next;
	while (uapres != &pjsua.pres_srv_list) {
	
	    PJ_LOG(3,(THIS_FILE, "  %10s %s",
		      pjsip_evsub_get_state_name(uapres->sub),
		      uapres->remote));

	    uapres = uapres->next;
	}
    }

    PJ_LOG(3,(THIS_FILE, "Dumping pjsua client subscriptions:"));
    if (pjsua.buddy_cnt == 0) {
	PJ_LOG(3,(THIS_FILE, "  - no buddy list - "));
    } else {
	for (i=0; i<pjsua.buddy_cnt; ++i) {

	    if (pjsua.buddies[i].sub) {
		PJ_LOG(3,(THIS_FILE, "  %10s %s",
			  pjsip_evsub_get_state_name(pjsua.buddies[i].sub),
			  pjsua.buddies[i].uri.ptr));
	    } else {
		PJ_LOG(3,(THIS_FILE, "  %10s %s",
			  "(null)",
			  pjsua.buddies[i].uri.ptr));
	    }
	}
    }
}

