/* $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/xpidf.h>
#include <pj/assert.h>
#include <pj/guid.h>
#include <pj/pool.h>
#include <pj/string.h>

static pj_str_t PRESENCE = { "presence", 8 };
static pj_str_t STATUS = { "status", 6 };
static pj_str_t OPEN = { "open", 4 };
static pj_str_t CLOSED = { "closed", 6 };
static pj_str_t URI = { "uri", 3 };
static pj_str_t ATOM = { "atom", 4 };
static pj_str_t ATOMID = { "atomid", 6 };
static pj_str_t ID = { "id", 2 };
static pj_str_t ADDRESS = { "address", 7 };
static pj_str_t SUBSCRIBE_PARAM = { ";method=SUBSCRIBE", 17 };
static pj_str_t PRESENTITY = { "presentity", 10 };
static pj_str_t EMPTY_STRING = { NULL, 0 };

static pj_xml_node* xml_create_node(pj_pool_t *pool, 
				    pj_str_t *name, const pj_str_t *value)
{
    pj_xml_node *node;

    node = pj_pool_alloc(pool, sizeof(pj_xml_node));
    pj_list_init(&node->attr_head);
    pj_list_init(&node->node_head);
    node->name = *name;
    if (value) pj_strdup(pool, &node->content, value);
    else node->content.ptr=NULL, node->content.slen=0;

    return node;
}

static pj_xml_attr* xml_create_attr(pj_pool_t *pool, pj_str_t *name,
				    const pj_str_t *value)
{
    pj_xml_attr *attr = pj_pool_alloc(pool, sizeof(*attr));
    attr->name = *name;
    pj_strdup(pool, &attr->value, value);
    return attr;
}


PJ_DEF(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri_cstr)
{
    pjxpidf_pres *pres;
    pj_xml_node *presentity;
    pj_xml_node *atom;
    pj_xml_node *addr;
    pj_xml_node *status;
    pj_xml_attr *attr;
    pj_str_t uri;
    pj_str_t tmp;

    /* <presence> */
    pres = xml_create_node(pool, &PRESENCE, NULL);

    /* <presentity> */
    presentity = xml_create_node(pool, &PRESENTITY, NULL);
    pj_xml_add_node(pres, presentity);

    /* uri attribute */
    uri.ptr = pj_pool_alloc(pool, uri_cstr->slen + SUBSCRIBE_PARAM.slen);
    pj_strcpy( &uri, uri_cstr);
    pj_strcat( &uri, &SUBSCRIBE_PARAM);
    attr = xml_create_attr(pool, &URI, &uri);
    pj_xml_add_attr(presentity, attr);

    /* <atom> */
    atom = xml_create_node(pool, &ATOM, NULL);
    pj_xml_add_node(pres, atom);

    /* atom id */
    pj_create_unique_string(pool, &tmp);
    attr = xml_create_attr(pool, &ATOMID, &tmp);
    pj_xml_add_attr(atom, attr);

    /* address */
    addr = xml_create_node(pool, &ADDRESS, NULL);
    pj_xml_add_node(atom, addr);

    /* address'es uri */
    attr = xml_create_attr(pool, &URI, uri_cstr);
    pj_xml_add_attr(addr, attr);

    /* status */
    status = xml_create_node(pool, &STATUS, NULL);
    pj_xml_add_node(addr, status);

    /* status attr */
    attr = xml_create_attr(pool, &STATUS, &OPEN);
    pj_xml_add_attr(status, attr);

    return pres;
}   



PJ_DEF(pjxpidf_pres*) pjxpidf_parse(pj_pool_t *pool, char *text, pj_size_t len)
{
    pjxpidf_pres *pres;
    pj_xml_node *node;

    pres = pj_xml_parse(pool, text, len);
    if (!pres)
	return NULL;

    /* Validate <presence> */
    if (pj_stricmp(&pres->name, &PRESENCE) != 0)
	return NULL;

    /* Validate <presentity> */
    node = pj_xml_find_node(pres, &PRESENTITY);
    if (node == NULL)
	return NULL;
    if (pj_xml_find_attr(node, &URI, NULL) == NULL)
	return NULL;

    /* Validate <atom> */
    node = pj_xml_find_node(pres, &ATOM);
    if (node == NULL)
	return NULL;
    if (pj_xml_find_attr(node, &ATOMID, NULL) == NULL && 
	pj_xml_find_attr(node, &ID, NULL) == NULL)
    {
	return NULL;
    }

    /* Address */
    node = pj_xml_find_node(node, &ADDRESS);
    if (node == NULL)
	return NULL;
    if (pj_xml_find_attr(node, &URI, NULL) == NULL)
	return NULL;


    /* Status */
    node = pj_xml_find_node(node, &STATUS);
    if (node == NULL)
	return NULL;
    if (pj_xml_find_attr(node, &STATUS, NULL) == NULL)
	return NULL;

    return pres;
}


PJ_DEF(int) pjxpidf_print( pjxpidf_pres *pres, char *text, pj_size_t len)
{
    return pj_xml_print(pres, text, len, PJ_TRUE);
}


PJ_DEF(pj_str_t*) pjxpidf_get_uri(pjxpidf_pres *pres)
{
    pj_xml_node *presentity;
    pj_xml_attr *attr;

    presentity = pj_xml_find_node(pres, &PRESENTITY);
    if (!presentity)
	return &EMPTY_STRING;

    attr = pj_xml_find_attr(presentity, &URI, NULL);
    if (!attr)
	return &EMPTY_STRING;

    return &attr->value;
}


PJ_DEF(pj_status_t) pjxpidf_set_uri(pj_pool_t *pool, pjxpidf_pres *pres, 
				    const pj_str_t *uri)
{
    pj_xml_node *presentity;
    pj_xml_node *atom;
    pj_xml_node *addr;
    pj_xml_attr *attr;
    pj_str_t dup_uri;

    presentity = pj_xml_find_node(pres, &PRESENTITY);
    if (!presentity) {
	pj_assert(0);
	return -1;
    }
    atom = pj_xml_find_node(pres, &ATOM);
    if (!atom) {
	pj_assert(0);
	return -1;
    }
    addr = pj_xml_find_node(atom, &ADDRESS);
    if (!addr) {
	pj_assert(0);
	return -1;
    }

    /* Set uri in presentity */
    attr = pj_xml_find_attr(presentity, &URI, NULL);
    if (!attr) {
	pj_assert(0);
	return -1;
    }
    pj_strdup(pool, &dup_uri, uri);
    attr->value = dup_uri;

    /* Set uri in address. */
    attr = pj_xml_find_attr(addr, &URI, NULL);
    if (!attr) {
	pj_assert(0);
	return -1;
    }
    attr->value = dup_uri;

    return 0;
}


PJ_DEF(pj_bool_t) pjxpidf_get_status(pjxpidf_pres *pres)
{
    pj_xml_node *atom;
    pj_xml_node *addr;
    pj_xml_node *status;
    pj_xml_attr *attr;

    atom = pj_xml_find_node(pres, &ATOM);
    if (!atom) {
	pj_assert(0);
	return PJ_FALSE;
    }
    addr = pj_xml_find_node(atom, &ADDRESS);
    if (!addr) {
	pj_assert(0);
	return PJ_FALSE;
    }
    status = pj_xml_find_node(addr, &STATUS);
    if (!status) {
	pj_assert(0);
	return PJ_FALSE;
    }
    attr = pj_xml_find_attr(status, &STATUS, NULL);
    if (!attr) {
	pj_assert(0);
	return PJ_FALSE;
    }

    return pj_stricmp(&attr->value, &OPEN)==0 ? PJ_TRUE : PJ_FALSE;
}


PJ_DEF(pj_status_t) pjxpidf_set_status(pjxpidf_pres *pres, pj_bool_t online_status)
{
    pj_xml_node *atom;
    pj_xml_node *addr;
    pj_xml_node *status;
    pj_xml_attr *attr;

    atom = pj_xml_find_node(pres, &ATOM);
    if (!atom) {
	pj_assert(0);
	return -1;
    }
    addr = pj_xml_find_node(atom, &ADDRESS);
    if (!addr) {
	pj_assert(0);
	return -1;
    }
    status = pj_xml_find_node(addr, &STATUS);
    if (!status) {
	pj_assert(0);
	return -1;
    }
    attr = pj_xml_find_attr(status, &STATUS, NULL);
    if (!attr) {
	pj_assert(0);
	return -1;
    }

    attr->value = ( online_status ? OPEN : CLOSED );
    return 0;
}

