/* $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/sip_tel_uri.h>
#include <pjsip/sip_msg.h>
#include <pjsip/sip_parser.h>
#include <pjsip/print_util.h>
#include <pj/pool.h>
#include <pj/assert.h>
#include <pj/string.h>
#include <pj/ctype.h>
#include <pj/except.h>
#include <pjlib-util/string.h>
#include <pjlib-util/scanner.h>

#define ALPHA
#define DIGITS		    "0123456789"
#define HEX		    "aAbBcCdDeEfF"
#define HEX_DIGITS	    DIGITS HEX
#define VISUAL_SEP	    "-.()"
#define PHONE_DIGITS	    DIGITS VISUAL_SEP
#define GLOBAL_DIGITS	    "+" PHONE_DIGITS
#define LOCAL_DIGITS	    HEX_DIGITS "*#" VISUAL_SEP
#define NUMBER_SPEC	    LOCAL_DIGITS GLOBAL_DIGITS
#define PHONE_CONTEXT	    ALPHA GLOBAL_DIGITS
//#define RESERVED	    ";/?:@&=+$,"
#define RESERVED	    "/:@&$,+"
#define MARK		    "-_.!~*'()"
#define UNRESERVED	    ALPHA DIGITS MARK
#define ESCAPED		    "%"
#define URIC		    RESERVED UNRESERVED ESCAPED "[]+"
#define PARAM_UNRESERVED    "[]/:&+$"
#define PARAM_CHAR	    PARAM_UNRESERVED UNRESERVED ESCAPED

static pj_cis_buf_t cis_buf;
static pj_cis_t pjsip_TEL_NUMBER_SPEC;
static pj_cis_t pjsip_TEL_EXT_VALUE_SPEC;
static pj_cis_t pjsip_TEL_PHONE_CONTEXT_SPEC;
static pj_cis_t pjsip_TEL_URIC_SPEC;
static pj_cis_t pjsip_TEL_VISUAL_SEP_SPEC;
static pj_cis_t pjsip_TEL_PNAME_SPEC;
static pj_cis_t pjsip_TEL_PVALUE_SPEC;
static pj_cis_t pjsip_TEL_PVALUE_SPEC_ESC;
static pj_cis_t pjsip_TEL_PARSING_PVALUE_SPEC;
static pj_cis_t pjsip_TEL_PARSING_PVALUE_SPEC_ESC;

static pj_str_t pjsip_ISUB_STR = { "isub", 4 };
static pj_str_t pjsip_EXT_STR = { "ext", 3 };
static pj_str_t pjsip_PH_CTX_STR = { "phone-context", 13 };


static const pj_str_t *tel_uri_get_scheme( const pjsip_tel_uri* );
static void *tel_uri_get_uri( pjsip_tel_uri* );
static pj_ssize_t tel_uri_print( pjsip_uri_context_e context,
				 const pjsip_tel_uri *url, 
				 char *buf, pj_size_t size);
static int tel_uri_cmp( pjsip_uri_context_e context,
			const pjsip_tel_uri *url1, const pjsip_tel_uri *url2);
static pjsip_tel_uri* tel_uri_clone(pj_pool_t *pool, const pjsip_tel_uri *rhs);
static void*	      tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,
				     pj_bool_t parse_params);

typedef const pj_str_t* (*P_GET_SCHEME)(const void*);
typedef void* 		(*P_GET_URI)(void*);
typedef pj_ssize_t 	(*P_PRINT_URI)(pjsip_uri_context_e,const void *,
				       char*,pj_size_t);
typedef int 		(*P_CMP_URI)(pjsip_uri_context_e, const void*, 
				     const void*);
typedef void* 		(*P_CLONE)(pj_pool_t*, const void*);

static pjsip_uri_vptr tel_uri_vptr = 
{
    (P_GET_SCHEME)	&tel_uri_get_scheme,
    (P_GET_URI) 	&tel_uri_get_uri,
    (P_PRINT_URI) 	&tel_uri_print,
    (P_CMP_URI)		&tel_uri_cmp,
    (P_CLONE)		&tel_uri_clone
};


PJ_DEF(pjsip_tel_uri*) pjsip_tel_uri_create(pj_pool_t *pool)
{
    pjsip_tel_uri *uri = PJ_POOL_ZALLOC_T(pool, pjsip_tel_uri);
    uri->vptr = &tel_uri_vptr;
    pj_list_init(&uri->other_param);
    return uri;
}


static const pj_str_t *tel_uri_get_scheme( const pjsip_tel_uri *uri )
{
    PJ_UNUSED_ARG(uri);
    return &pjsip_parser_const()->pjsip_TEL_STR;
}

static void *tel_uri_get_uri( pjsip_tel_uri *uri )
{
    return uri;
}


pj_status_t pjsip_tel_uri_subsys_init(void)
{
    pj_status_t status;

    pj_cis_buf_init(&cis_buf);

    status = pj_cis_init(&cis_buf, &pjsip_TEL_EXT_VALUE_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_str(&pjsip_TEL_EXT_VALUE_SPEC, PHONE_DIGITS);

    status = pj_cis_init(&cis_buf, &pjsip_TEL_NUMBER_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_str(&pjsip_TEL_NUMBER_SPEC, NUMBER_SPEC);

    status = pj_cis_init(&cis_buf, &pjsip_TEL_VISUAL_SEP_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_str(&pjsip_TEL_VISUAL_SEP_SPEC, VISUAL_SEP);

    status = pj_cis_init(&cis_buf, &pjsip_TEL_PHONE_CONTEXT_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_alpha(&pjsip_TEL_PHONE_CONTEXT_SPEC);
    pj_cis_add_num(&pjsip_TEL_PHONE_CONTEXT_SPEC);
    pj_cis_add_str(&pjsip_TEL_PHONE_CONTEXT_SPEC, PHONE_CONTEXT);

    status = pj_cis_init(&cis_buf, &pjsip_TEL_URIC_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_alpha(&pjsip_TEL_URIC_SPEC);
    pj_cis_add_num(&pjsip_TEL_URIC_SPEC);
    pj_cis_add_str(&pjsip_TEL_URIC_SPEC, URIC);

    status = pj_cis_init(&cis_buf, &pjsip_TEL_PNAME_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_alpha(&pjsip_TEL_PNAME_SPEC);
    pj_cis_add_num(&pjsip_TEL_PNAME_SPEC);
    pj_cis_add_str(&pjsip_TEL_PNAME_SPEC, "-");

    status = pj_cis_init(&cis_buf, &pjsip_TEL_PVALUE_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_alpha(&pjsip_TEL_PVALUE_SPEC);
    pj_cis_add_num(&pjsip_TEL_PVALUE_SPEC);
    pj_cis_add_str(&pjsip_TEL_PVALUE_SPEC, PARAM_CHAR);

    status = pj_cis_dup(&pjsip_TEL_PVALUE_SPEC_ESC, &pjsip_TEL_PVALUE_SPEC);
    pj_cis_del_str(&pjsip_TEL_PVALUE_SPEC_ESC, "%");

    status = pj_cis_dup(&pjsip_TEL_PARSING_PVALUE_SPEC, &pjsip_TEL_URIC_SPEC);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
    pj_cis_add_cis(&pjsip_TEL_PARSING_PVALUE_SPEC, &pjsip_TEL_PVALUE_SPEC);
    pj_cis_add_str(&pjsip_TEL_PARSING_PVALUE_SPEC, "=");

    status = pj_cis_dup(&pjsip_TEL_PARSING_PVALUE_SPEC_ESC, 
			&pjsip_TEL_PARSING_PVALUE_SPEC);
    pj_cis_del_str(&pjsip_TEL_PARSING_PVALUE_SPEC_ESC, "%");

    status = pjsip_register_uri_parser("tel", &tel_uri_parse);
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);

    return PJ_SUCCESS;
}

/* Print tel: URI */
static pj_ssize_t tel_uri_print( pjsip_uri_context_e context,
				 const pjsip_tel_uri *uri, 
				 char *buf, pj_size_t size)
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf+size-1;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    PJ_UNUSED_ARG(context);

    /* Print scheme. */
    copy_advance(buf, pc->pjsip_TEL_STR);
    *buf++ = ':';

    /* Print number. */
    copy_advance_escape(buf, uri->number, pjsip_TEL_NUMBER_SPEC);

    /* ISDN sub-address or extension must appear first. */

    /* Extension param. */
    copy_advance_pair_escape(buf, ";ext=", 5, uri->ext_param, 
			     pjsip_TEL_EXT_VALUE_SPEC);

    /* ISDN sub-address. */
    copy_advance_pair_escape(buf, ";isub=", 6, uri->isub_param, 
			     pjsip_TEL_URIC_SPEC);

    /* Followed by phone context, if present. */
    copy_advance_pair_escape(buf, ";phone-context=", 15, uri->context, 
			     pjsip_TEL_PHONE_CONTEXT_SPEC);


    /* Print other parameters. */
    printed = (int)pjsip_param_print_on(&uri->other_param, buf, (endbuf-buf), 
					&pjsip_TEL_PNAME_SPEC, 
					&pjsip_TEL_PVALUE_SPEC, ';');
    if (printed < 0)
	return -1;
    buf += printed;

    *buf = '\0';

    return (buf-startbuf);
}

/* Compare two numbers, according to RFC 3966:
 *  - both must be either local or global numbers.
 *  - The 'global-number-digits' and the 'local-number-digits' must be
 *    equal, after removing all visual separators.
 */
PJ_DEF(int) pjsip_tel_nb_cmp(const pj_str_t *number1, const pj_str_t *number2)
{
    const char *s1 = number1->ptr,
	       *e1 = number1->ptr + number1->slen,
	       *s2 = number2->ptr,
	       *e2 = number2->ptr + number2->slen;

    /* Compare each number, ignoreing visual separators. */
    while (s1!=e1 && s2!=e2) {
	int diff;

	if (pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s1)) {
	    ++s1;
	    continue;
	}
	if (pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s2)) {
	    ++s2;
	    continue;
	}

	diff = pj_tolower(*s1) - pj_tolower(*s2);
	if (!diff) {
	    ++s1, ++s2;
	    continue;
	} else
	    return diff;
    }

    /* Exhaust remaining visual separators. */
    while (s1!=e1 && pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s1))
	++s1;
    while (s2!=e2 && pj_cis_match(&pjsip_TEL_VISUAL_SEP_SPEC, *s2))
	++s2;

    if (s1==e1 && s2==e2)
	return 0;
    else if (s1==e1)
	return -1;
    else
	return 1;
}

/* Compare two tel: URI */
static int tel_uri_cmp( pjsip_uri_context_e context,
			const pjsip_tel_uri *url1, const pjsip_tel_uri *url2)
{
    int result;

    PJ_UNUSED_ARG(context);

    /* Scheme must match. */
    if (url1->vptr != url2->vptr)
	return -1;

    /* Compare number. */
    result = pjsip_tel_nb_cmp(&url1->number, &url2->number);
    if (result != 0)
	return result;

    /* Compare phone-context as hostname or as as global nb. */
    if (url1->context.slen) {
	if (*url1->context.ptr != '+')
	    result = pj_stricmp(&url1->context, &url2->context);
	else
	    result = pjsip_tel_nb_cmp(&url1->context, &url2->context);

	if (result != 0)
	    return result;

    } else if (url2->context.slen)
	return -1;

    /* Compare extension. */
    if (url1->ext_param.slen) {
	result = pjsip_tel_nb_cmp(&url1->ext_param, &url2->ext_param);
	if (result != 0)
	    return result;
    }

    /* Compare isub bytes by bytes. */
    if (url1->isub_param.slen) {
	result = pj_stricmp(&url1->isub_param, &url2->isub_param);
	if (result != 0)
	    return result;
    }

    /* Other parameters are compared regardless of the order.
     * If one URI has parameter not found in the other URI, the URIs are
     * not equal.
     */
    if (url1->other_param.next != &url1->other_param) {
	const pjsip_param *p1, *p2;
	int cnt1 = 0, cnt2 = 0;

	p1 = url1->other_param.next;
	while (p1 != &url1->other_param) {
	    p2 = pjsip_param_cfind(&url2->other_param, &p1->name);
	    if (!p2 )
		return 1;

	    result = pj_stricmp(&p1->value, &p2->value);
	    if (result != 0)
		return result;

	    p1 = p1->next;
	    ++cnt1;
	}

	p2 = url2->other_param.next;
	while (p2 != &url2->other_param)
	    ++cnt2, p2 = p2->next;

	if (cnt1 < cnt2)
	    return -1;
	else if (cnt1 > cnt2)
	    return 1;

    } else if (url2->other_param.next != &url2->other_param)
	return -1;

    /* Equal. */
    return 0;
}

/* Clone tel: URI */
static pjsip_tel_uri* tel_uri_clone(pj_pool_t *pool, const pjsip_tel_uri *rhs)
{
    pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);

    pj_strdup(pool, &uri->number, &rhs->number);
    pj_strdup(pool, &uri->context, &rhs->context);
    pj_strdup(pool, &uri->ext_param, &rhs->ext_param);
    pj_strdup(pool, &uri->isub_param, &rhs->isub_param);
    pjsip_param_clone(pool, &uri->other_param, &rhs->other_param);

    return uri;
}

/* Parse tel: URI 
 * THis actually returns (pjsip_tel_uri *) type.
 */
static void* tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,
			    pj_bool_t parse_params)
{
    pjsip_tel_uri *uri;
    pj_str_t token;
    int skip_ws = scanner->skip_ws;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    scanner->skip_ws = 0;

    /* Parse scheme. */
    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &token);
    if (pj_scan_get_char(scanner) != ':')
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
    if (pj_stricmp_alnum(&token, &pc->pjsip_TEL_STR) != 0)
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);

    /* Create URI */
    uri = pjsip_tel_uri_create(pool);

    /* Get the phone number. */
#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
    pj_scan_get_unescape(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);
#else
    pj_scan_get(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);
    uri->number = pj_str_unescape(pool, &uri->number);
#endif

    /* Get all parameters. */
    if (parse_params && *scanner->curptr==';') {
	pj_str_t pname, pvalue;
	const pjsip_parser_const_t *pc = pjsip_parser_const();

	do {
	    /* Eat the ';' separator. */
	    pj_scan_get_char(scanner);

	    /* Get pname. */
	    pj_scan_get(scanner, &pc->pjsip_PARAM_CHAR_SPEC, &pname);

	    if (*scanner->curptr == '=') {
		pj_scan_get_char(scanner);

#		if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
		    pj_scan_get_unescape(scanner, 
					 &pjsip_TEL_PARSING_PVALUE_SPEC_ESC,
					 &pvalue);
#		else
		    pj_scan_get(scanner, &pjsip_TEL_PARSING_PVALUE_SPEC, 
				&pvalue);
		    pvalue = pj_str_unescape(pool, &pvalue);
#		endif

	    } else {
		pvalue.slen = 0;
		pvalue.ptr = NULL;
	    }

	    /* Save the parameters. */
	    if (pj_stricmp_alnum(&pname, &pjsip_ISUB_STR)==0) {
		uri->isub_param = pvalue;
	    } else if (pj_stricmp_alnum(&pname, &pjsip_EXT_STR)==0) {
		uri->ext_param = pvalue;
	    } else if (pj_stricmp_alnum(&pname, &pjsip_PH_CTX_STR)==0) {
		uri->context = pvalue;
	    } else {
		pjsip_param *param = PJ_POOL_ALLOC_T(pool, pjsip_param);
		param->name = pname;
		param->value = pvalue;
		pj_list_insert_before(&uri->other_param, param);
	    }

	} while (*scanner->curptr==';');
    }

    scanner->skip_ws = skip_ws;
    pj_scan_skip_whitespace(scanner);
    return uri;
}

