/* $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/iscomposing.h>
#include <pjsip-simple/errno.h>
#include <pjsip/sip_msg.h>
#include <pjlib-util/errno.h>
#include <pj/pool.h>
#include <pj/string.h>


/* MIME */
static const pj_str_t STR_MIME_TYPE = { "application", 11 };
static const pj_str_t STR_MIME_SUBTYPE = { "im-iscomposing+xml", 18 };


/* XML node constants. */
static const pj_str_t STR_ISCOMPOSING	= { "isComposing", 11 };
static const pj_str_t STR_STATE		= { "state", 5 };
static const pj_str_t STR_ACTIVE	= { "active", 6 };
static const pj_str_t STR_IDLE		= { "idle", 4 };
static const pj_str_t STR_LASTACTIVE	= { "lastactive", 10 };
static const pj_str_t STR_CONTENTTYPE	= { "contenttype", 11 };
static const pj_str_t STR_REFRESH	= { "refresh", 7 };


/* XML attributes constants */
static const pj_str_t STR_XMLNS_NAME =     { "xmlns", 5 };
static const pj_str_t STR_XMLNS_VAL =      { "urn:ietf:params:xml:ns:im-iscomposing", 37 };
static const pj_str_t STR_XMLNS_XSI_NAME = { "xmlns:xsi", 9 };
static const pj_str_t STR_XMLNS_XSI_VAL  = { "http://www.w3.org/2001/XMLSchema-instance", 41 };
static const pj_str_t STR_XSI_SLOC_NAME =  { "xsi:schemaLocation", 18 };
static const pj_str_t STR_XSI_SLOC_VAL =   { "urn:ietf:params:xml:ns:im-composing iscomposing.xsd", 51 };


PJ_DEF(pj_xml_node*) pjsip_iscomposing_create_xml( pj_pool_t *pool,
						   pj_bool_t is_composing,
						   const pj_time_val *lst_actv,
						   const pj_str_t *content_tp,
						   int refresh)
{
    pj_xml_node *doc, *node;
    pj_xml_attr *attr;

    /* Root document. */
    doc = pj_xml_node_new(pool, &STR_ISCOMPOSING);

    /* Add attributes */
    attr = pj_xml_attr_new(pool, &STR_XMLNS_NAME, &STR_XMLNS_VAL);
    pj_xml_add_attr(doc, attr);

    attr = pj_xml_attr_new(pool, &STR_XMLNS_XSI_NAME, &STR_XMLNS_XSI_VAL);
    pj_xml_add_attr(doc, attr);

    attr = pj_xml_attr_new(pool, &STR_XSI_SLOC_NAME, &STR_XSI_SLOC_VAL);
    pj_xml_add_attr(doc, attr);


    /* Add state. */
    node = pj_xml_node_new(pool, &STR_STATE);
    if (is_composing)
	node->content = STR_ACTIVE;
    else
	node->content = STR_IDLE;
    pj_xml_add_node(doc, node);

    /* Add lastactive, if any. */
    PJ_UNUSED_ARG(lst_actv);
    //if (!is_composing && lst_actv) {
    //	PJ_TODO(IMPLEMENT_LAST_ACTIVE_ATTRIBUTE);
    //}

    /* Add contenttype, if any. */
    if (content_tp) {
	node = pj_xml_node_new(pool, &STR_CONTENTTYPE);
	pj_strdup(pool, &node->content, content_tp);
	pj_xml_add_node(doc, node);
    }

    /* Add refresh, if any. */
    if (is_composing && refresh > 1 && refresh < 3601) {
	node = pj_xml_node_new(pool, &STR_REFRESH);
	node->content.ptr = pj_pool_alloc(pool, 10);
	node->content.slen = pj_utoa(refresh, node->content.ptr);
	pj_xml_add_node(doc, node);
    }

    /* Done! */

    return doc;
}



/*
 * Function to print XML message body.
 */
static int xml_print_body( struct pjsip_msg_body *msg_body, 
			   char *buf, pj_size_t size)
{
    return pj_xml_print(msg_body->data, buf, size, PJ_TRUE);
}


/*
 * Function to clone XML document.
 */
static void* xml_clone_data(pj_pool_t *pool, const void *data, unsigned len)
{
    PJ_UNUSED_ARG(len);
    return pj_xml_clone( pool, data);
}



PJ_DEF(pjsip_msg_body*) pjsip_iscomposing_create_body( pj_pool_t *pool,
						   pj_bool_t is_composing,
						   const pj_time_val *lst_actv,
						   const pj_str_t *content_tp,
						   int refresh)
{
    pj_xml_node *doc;
    pjsip_msg_body *body;

    doc = pjsip_iscomposing_create_xml( pool, is_composing, lst_actv,
					content_tp, refresh);
    if (doc == NULL)
	return NULL;


    body = pj_pool_zalloc(pool, sizeof(pjsip_msg_body));
    body->content_type.type = STR_MIME_TYPE;
    body->content_type.subtype = STR_MIME_SUBTYPE;

    body->data = doc;
    body->len = 0;

    body->print_body = &xml_print_body;
    body->clone_data = &xml_clone_data;

    return body;
}


PJ_DEF(pj_status_t) pjsip_iscomposing_parse( pj_pool_t *pool,
					     char *msg,
					     pj_size_t len,
					     pj_bool_t *p_is_composing,
					     pj_str_t **p_last_active,
					     pj_str_t **p_content_type,
					     int *p_refresh )
{
    pj_xml_node *doc, *node;

    /* Set defaults: */
    if (p_is_composing) *p_is_composing = PJ_FALSE;
    if (p_last_active) *p_last_active = NULL; 
    if (p_content_type) *p_content_type = NULL;

    /* Parse XML */
    doc = pj_xml_parse( pool, msg, len);
    if (!doc)
	return PJLIB_UTIL_EINXML;

    /* Root document must be "isComposing" */
    if (pj_stricmp(&doc->name, &STR_ISCOMPOSING) != 0)
	return PJSIP_SIMPLE_EBADISCOMPOSE;

    /* Get the status. */
    if (p_is_composing) {
	node = pj_xml_find_node(doc, &STR_STATE);
	if (node == NULL)
	    return PJSIP_SIMPLE_EBADISCOMPOSE;
	*p_is_composing = (pj_stricmp(&node->content, &STR_ACTIVE)==0);
    }

    /* Get last active. */
    if (p_last_active) {
	node = pj_xml_find_node(doc, &STR_LASTACTIVE);
	if (node)
	    *p_last_active = &node->content;
    }

    /* Get content type */
    if (p_content_type) {
	node = pj_xml_find_node(doc, &STR_CONTENTTYPE);
	if (node)
	    *p_content_type = &node->content;
    }

    /* Get refresh */
    if (p_refresh) {
	node = pj_xml_find_node(doc, &STR_REFRESH);
	if (node)
	    *p_refresh = pj_strtoul(&node->content);
    }

    return PJ_SUCCESS;
}


