/* $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 <pjsip_simple/presence.h>
#include <pjsip/sip_transport.h>
#include <pj/pool.h>
#include <pj/string.h>
#include <pj/guid.h>
#include <pj/os.h>
#include <stdio.h>

/* Forward declarations. */
static void on_query_subscribe(pjsip_rx_data *rdata, int *status);
static void on_subscribe(pjsip_event_sub *sub, pjsip_rx_data *rdata,
			 pjsip_event_sub_cb **cb, int *expires);
static void on_sub_terminated(pjsip_event_sub *sub, const pj_str_t *reason);
static void on_sub_received_refresh(pjsip_event_sub *sub, pjsip_rx_data *rdata);
static void on_received_notify(pjsip_event_sub *sub, pjsip_rx_data *rdata);

/* Some string constants. */
static pj_str_t PRESENCE_EVENT = { "presence", 8 };

/* Accept types. */
static pj_str_t accept_names[] = {
    { "application/pidf+xml", 20 },
    { "application/xpidf+xml", 21 }
};
static pjsip_media_type accept_types[] = {
    {
	{ "application", 11 },
	{ "pidf+xml", 8 }
    },
    {
	{ "application", 11 },
	{ "xpidf+xml", 9 }
    }
};

/* Callback that is registered by application. */
static pjsip_presence_cb cb;

/* Package callback to be register to event_notify */
static pjsip_event_sub_pkg_cb pkg_cb = { &on_query_subscribe,
					 &on_subscribe };

/* Global/static callback to be registered to event_notify */
static pjsip_event_sub_cb sub_cb = { &on_sub_terminated,
				     &on_sub_received_refresh,
				     NULL,
				     &on_received_notify,
				     NULL };

/*
 * Initialize presence module.
 * This will register event package "presence" to event framework.
 */
PJ_DEF(void) pjsip_presence_init(const pjsip_presence_cb *pcb)
{
    pj_memcpy(&cb, pcb, sizeof(*pcb));
    pjsip_event_sub_register_pkg( &PRESENCE_EVENT, 
				  sizeof(accept_names)/sizeof(accept_names[0]),
				  accept_names,
				  &pkg_cb);
}

/*
 * Create presence subscription.
 */
PJ_DEF(pjsip_presentity*) pjsip_presence_create( pjsip_endpoint *endpt,
						 const pj_str_t *local_url,
						 const pj_str_t *remote_url,
						 int expires,
						 void *user_data )
{
    pjsip_event_sub *sub;
    pjsip_presentity *pres;

    if (expires < 0)
	expires = 300;

    /* Create event subscription */
    sub = pjsip_event_sub_create(endpt, local_url, remote_url, &PRESENCE_EVENT, 
				 expires, 
				 sizeof(accept_names)/sizeof(accept_names[0]),
				 accept_names,
				 NULL, &sub_cb);
    if (!sub)
	return NULL;

    /* Allocate presence descriptor. */
    pres = pj_pool_calloc(sub->pool, 1, sizeof(*pres));
    pres->sub = sub;
    pres->user_data = user_data;
    sub->user_data = pres;

    return pres;
}

/*
 * Send SUBSCRIBE.
 */
PJ_DEF(pj_status_t) pjsip_presence_subscribe( pjsip_presentity *pres )
{
    return pjsip_event_sub_subscribe( pres->sub );
}

/*
 * Set credentials to be used for outgoing requests.
 */
PJ_DEF(pj_status_t) pjsip_presence_set_credentials( pjsip_presentity *pres,
						    int count,
						    const pjsip_cred_info cred[])
{
    return pjsip_event_sub_set_credentials(pres->sub, count, cred);
}

/*
 * Set route-set.
 */
PJ_DEF(pj_status_t) pjsip_presence_set_route_set( pjsip_presentity *pres,
						  const pjsip_route_hdr *hdr )
{
    return pjsip_event_sub_set_route_set( pres->sub, hdr );
}

/*
 * Unsubscribe.
 */
PJ_DEF(pj_status_t) pjsip_presence_unsubscribe( pjsip_presentity *pres )
{
    return pjsip_event_sub_unsubscribe(pres->sub);
}

/*
 * This is the pjsip_msg_body callback to print XML body.
 */
static int print_xml(pjsip_msg_body *body, char *buf, pj_size_t size)
{
    return pj_xml_print( body->data, buf, size, PJ_TRUE );
}

/*
 * Create and initialize PIDF document and msg body (notifier only).
 */
static pj_status_t init_presence_info( pjsip_presentity *pres )
{
    pj_str_t uri;
    pj_pool_t *pool = pres->sub->pool;
    char tmp[PJSIP_MAX_URL_SIZE];
    pjpidf_tuple *tuple;
    const pjsip_media_type *content_type = NULL;

    pj_assert(pres->uas_body == NULL);

    /* Make entity_id */
    uri.ptr = tmp;
    uri.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, pres->sub->from->uri, 
			      tmp, sizeof(tmp));
    if (uri.slen < 0)
	return -1;

    if (pres->pres_type == PJSIP_PRES_TYPE_PIDF) {
	pj_str_t s;

	/* Create <presence>. */
	pres->uas_data.pidf = pjpidf_create(pool, &s);

	/* Create <tuple> */
	pj_create_unique_string(pool, &s);
	tuple = pjpidf_pres_add_tuple(pool, pres->uas_data.pidf, &s);

	/* Set <contact> */
	s.ptr = tmp;
	s.slen = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, pres->sub->contact->uri, tmp, sizeof(tmp));
	if (s.slen < 0)
	    return -1;
	pjpidf_tuple_set_contact(pool, tuple, &s);

	/* Content-Type */
	content_type = &accept_types[PJSIP_PRES_TYPE_PIDF];

    } else if (pres->pres_type == PJSIP_PRES_TYPE_XPIDF) {

	/* Create XPIDF */
	pres->uas_data.xpidf = pjxpidf_create(pool, &uri);

	/* Content-Type. */
	content_type = &accept_types[PJSIP_PRES_TYPE_XPIDF];
    }

    /* Create message body */
    pres->uas_body = pj_pool_alloc(pool, sizeof(pjsip_msg_body));
    pres->uas_body->content_type = *content_type;
    pres->uas_body->data = pres->uas_data.pidf;
    pres->uas_body->len = 0;
    pres->uas_body->print_body = &print_xml;

    return 0;
}

/*
 * Send NOTIFY and set subscription state.
 */
PJ_DEF(pj_status_t) pjsip_presence_notify( pjsip_presentity *pres,
					   pjsip_event_sub_state state,
					   pj_bool_t is_online )
{
    pj_str_t reason = { "", 0 };

    if (pres->uas_data.pidf == NULL) {
	if (init_presence_info(pres) != 0)
	    return -1;
    }

    /* Update basic status in PIDF/XPIDF document. */
    if (pres->pres_type == PJSIP_PRES_TYPE_PIDF) {
	pjpidf_tuple *first;
	pjpidf_status *status;
	pj_time_val now;
	pj_parsed_time pnow;

	first = pjpidf_op.pres.get_first_tuple(pres->uas_data.pidf);
	pj_assert(first);
	status = pjpidf_op.tuple.get_status(first);
	pj_assert(status);
	pjpidf_op.status.set_basic_open(status, is_online);

	/* Update timestamp. */
	if (pres->timestamp.ptr == 0) {
	    pres->timestamp.ptr = pj_pool_alloc(pres->sub->pool, 24);
	}
	pj_gettimeofday(&now);
	pj_time_decode(&now, &pnow);
	pres->timestamp.slen = sprintf(pres->timestamp.ptr,
				       "%04d-%02d-%02dT%02d:%02d:%02dZ",
				       pnow.year, pnow.mon, pnow.day,
				       pnow.hour, pnow.min, pnow.sec);
	pjpidf_op.tuple.set_timestamp_np(pres->sub->pool, first, &pres->timestamp);

    } else if (pres->pres_type == PJSIP_PRES_TYPE_XPIDF) {
	pjxpidf_set_status( pres->uas_data.xpidf, is_online );

    } else {
	pj_assert(0);
    }

    /* Send notify. */
    return pjsip_event_sub_notify( pres->sub, state, &reason, pres->uas_body);
}

/*
 * Destroy subscription (can be called for both subscriber and notifier).
 */
PJ_DEF(pj_status_t) pjsip_presence_destroy( pjsip_presentity *pres )
{
    return pjsip_event_sub_destroy(pres->sub);
}

/*
 * This callback is called by event framework to query whether we want to
 * accept an incoming subscription.
 */
static void on_query_subscribe(pjsip_rx_data *rdata, int *status)
{
    if (cb.accept_presence) {
	(*cb.accept_presence)(rdata, status);
    }
}

/*
 * This callback is called by event framework after we accept the incoming
 * subscription, to notify about the new subscription instance.
 */
static void on_subscribe(pjsip_event_sub *sub, pjsip_rx_data *rdata,
			 pjsip_event_sub_cb **set_sub_cb, int *expires)
{
    pjsip_presentity *pres;
    pjsip_accept_hdr *accept;

    pres = pj_pool_calloc(sub->pool, 1, sizeof(*pres));
    pres->sub = sub;
    pres->pres_type = PJSIP_PRES_TYPE_PIDF;
    sub->user_data = pres;
    *set_sub_cb = &sub_cb;

    accept = pjsip_msg_find_hdr(rdata->msg, PJSIP_H_ACCEPT, NULL);
    if (accept) {
	unsigned i;
	int found = 0;
	for (i=0; i<accept->count && !found; ++i) {
	    int j;
	    for (j=0; j<sizeof(accept_names)/sizeof(accept_names[0]); ++j) {
		if (!pj_stricmp(&accept->values[i], &accept_names[j])) {
		    pres->pres_type = j;
		    found = 1;
		    break;
		}
	    }
	}
	pj_assert(found );
    }

    (*cb.on_received_request)(pres, rdata, expires);
}

/*
 * This callback is called by event framework when the subscription is
 * terminated.
 */
static void on_sub_terminated(pjsip_event_sub *sub, const pj_str_t *reason)
{
    pjsip_presentity *pres = sub->user_data;
    if (cb.on_terminated)
	(*cb.on_terminated)(pres, reason);
}

/*
 * This callback is called by event framework when it receives incoming
 * SUBSCRIBE request to refresh the subscription.
 */
static void on_sub_received_refresh(pjsip_event_sub *sub, pjsip_rx_data *rdata)
{
    pjsip_presentity *pres = sub->user_data;
    if (cb.on_received_refresh)
	(*cb.on_received_refresh)(pres, rdata);
}

/*
 * This callback is called by event framework when it receives incoming
 * NOTIFY request.
 */
static void on_received_notify(pjsip_event_sub *sub, pjsip_rx_data *rdata)
{
    pjsip_presentity *pres = sub->user_data;

    if (cb.on_received_update) {
	pj_status_t is_open;
	pjsip_msg_body *body;
	int i;

	body = rdata->msg->body;
	if (!body)
	    return;

	for (i=0; i<sizeof(accept_types)/sizeof(accept_types[0]); ++i) {
	    if (!pj_stricmp(&body->content_type.type, &accept_types[i].type) &&
		!pj_stricmp(&body->content_type.subtype, &accept_types[i].subtype))
	    {
		break;
	    }
	}

	if (i==PJSIP_PRES_TYPE_PIDF) {
	    pjpidf_pres *pres;
	    pjpidf_tuple *tuple;
	    pjpidf_status *status;

	    pres = pjpidf_parse(rdata->pool, body->data, body->len);
	    if (!pres)
		return;
	    tuple = pjpidf_pres_get_first_tuple(pres);
	    if (!tuple)
		return;
	    status = pjpidf_tuple_get_status(tuple);
	    if (!status)
		return;
	    is_open = pjpidf_status_is_basic_open(status);

	} else if (i==PJSIP_PRES_TYPE_XPIDF) {
	    pjxpidf_pres *pres;

	    pres = pjxpidf_parse(rdata->pool, body->data, body->len);
	    if (!pres)
		return;
	    is_open = pjxpidf_get_status(pres);

	} else {
	    return;
	}

	(*cb.on_received_update)(pres, is_open);
    }
}

