/* $Id$ */
/* 
 * Copyright (C) 2008-2009 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-ua/sip_replaces.h>
#include <pjsip-ua/sip_inv.h>
#include <pjsip/print_util.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_errno.h>
#include <pjsip/sip_parser.h>
#include <pjsip/sip_transport.h>
#include <pjsip/sip_ua_layer.h>
#include <pjsip/sip_util.h>
#include <pj/assert.h>
#include <pj/pool.h>
#include <pj/string.h>


/*
 * Replaces header vptr.
 */
static int replaces_hdr_print( pjsip_replaces_hdr *hdr, 
			       char *buf, pj_size_t size);
static pjsip_replaces_hdr* replaces_hdr_clone( pj_pool_t *pool, 
					       const pjsip_replaces_hdr *hdr);
static pjsip_replaces_hdr* replaces_hdr_shallow_clone( pj_pool_t *pool,
						       const pjsip_replaces_hdr*);

static pjsip_hdr_vptr replaces_hdr_vptr = 
{
    (pjsip_hdr_clone_fptr) &replaces_hdr_clone,
    (pjsip_hdr_clone_fptr) &replaces_hdr_shallow_clone,
    (pjsip_hdr_print_fptr) &replaces_hdr_print,
};

/* Globals */
static pjsip_endpoint *the_endpt;

PJ_DEF(pjsip_replaces_hdr*) pjsip_replaces_hdr_create(pj_pool_t *pool)
{
    pjsip_replaces_hdr *hdr = PJ_POOL_ZALLOC_T(pool, pjsip_replaces_hdr);
    hdr->type = PJSIP_H_OTHER;
    hdr->name.ptr = "Replaces";
    hdr->name.slen = 8;
    hdr->vptr = &replaces_hdr_vptr;
    pj_list_init(hdr);
    pj_list_init(&hdr->other_param);
    return hdr;
}

static int replaces_hdr_print( pjsip_replaces_hdr *hdr, 
			       char *buf, pj_size_t size)
{
    char *p = buf;
    char *endbuf = buf+size;
    int printed;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    copy_advance(p, hdr->name);
    *p++ = ':';
    *p++ = ' ';

    copy_advance(p, hdr->call_id);
    copy_advance_pair(p, ";to-tag=", 8, hdr->to_tag);
    copy_advance_pair(p, ";from-tag=", 10, hdr->from_tag);

    if (hdr->early_only) {
	const pj_str_t str_early_only = { ";early-only", 11 };
	copy_advance(p, str_early_only);
    }
    
    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return printed;

    p += printed;
    return p - buf;
}

static pjsip_replaces_hdr* replaces_hdr_clone( pj_pool_t *pool, 
					       const pjsip_replaces_hdr *rhs)
{
    pjsip_replaces_hdr *hdr = pjsip_replaces_hdr_create(pool);
    pj_strdup(pool, &hdr->call_id, &rhs->call_id);
    pj_strdup(pool, &hdr->to_tag, &rhs->to_tag);
    pj_strdup(pool, &hdr->from_tag, &rhs->from_tag);
    hdr->early_only = rhs->early_only;
    pjsip_param_clone(pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}

static pjsip_replaces_hdr* 
replaces_hdr_shallow_clone( pj_pool_t *pool,
			    const pjsip_replaces_hdr *rhs )
{
    pjsip_replaces_hdr *hdr = PJ_POOL_ALLOC_T(pool, pjsip_replaces_hdr);
    pj_memcpy(hdr, rhs, sizeof(*hdr));
    pjsip_param_shallow_clone(pool, &hdr->other_param, &rhs->other_param);
    return hdr;
}


/*
 * Parse Replaces header.
 */
static pjsip_hdr *parse_hdr_replaces(pjsip_parse_ctx *ctx)
{
    pjsip_replaces_hdr *hdr = pjsip_replaces_hdr_create(ctx->pool);
    const pj_str_t to_tag = { "to-tag", 6 };
    const pj_str_t from_tag = { "from-tag", 8 };
    const pj_str_t early_only_tag = { "early-only", 10 };

    /*pj_scan_get(ctx->scanner, &pjsip_TOKEN_SPEC, &hdr->call_id);*/
    /* Get Call-ID (until ';' is found). using pjsip_TOKEN_SPEC doesn't work
     * because it stops parsing when '@' character is found.
     */
    pj_scan_get_until_ch(ctx->scanner, ';', &hdr->call_id);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	if (pj_stricmp(&pname, &to_tag)==0) {
	    hdr->to_tag = pvalue;
	} else if (pj_stricmp(&pname, &from_tag)==0) {
	    hdr->from_tag = pvalue;
	} else if (pj_stricmp(&pname, &early_only_tag)==0) {
	    hdr->early_only = PJ_TRUE;
	} else {
	    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
	    param->name = pname;
	    param->value = pvalue;
	    pj_list_push_back(&hdr->other_param, param);
	}
    }
    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}

/*
 * Initialize Replaces support in PJSIP. 
 */
PJ_DEF(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt)
{
    pj_status_t status;
    const pj_str_t STR_REPLACES = { "replaces", 8 };
    static pj_bool_t is_initialized;

    the_endpt = endpt;

    if (is_initialized)
	return PJ_SUCCESS;

    /* Register Replaces header parser */
    status = pjsip_register_hdr_parser( "Replaces", NULL, 
				        &parse_hdr_replaces);
    if (status != PJ_SUCCESS)
	return status;

    /* Register "replaces" capability */
    status = pjsip_endpt_add_capability(endpt, NULL, PJSIP_H_SUPPORTED, NULL,
					1, &STR_REPLACES);

    is_initialized = PJ_TRUE;
    return PJ_SUCCESS;
}


/*
 * Verify that incoming request with Replaces header can be processed.
 */
PJ_DEF(pj_status_t) pjsip_replaces_verify_request( pjsip_rx_data *rdata,
						   pjsip_dialog **p_dlg,
						   pj_bool_t lock_dlg,
						   pjsip_tx_data **p_tdata)
{
    const pj_str_t STR_REPLACES = { "Replaces", 8 };
    pjsip_replaces_hdr *rep_hdr;
    int code = 200;
    const char *warn_text = NULL;
    pjsip_hdr res_hdr_list;
    pjsip_dialog *dlg = NULL;
    pjsip_inv_session *inv;
    pj_status_t status = PJ_SUCCESS;

    PJ_ASSERT_RETURN(rdata && p_dlg, PJ_EINVAL);

    /* Check that pjsip_replaces_init_module() has been called. */
    PJ_ASSERT_RETURN(the_endpt != NULL, PJ_EINVALIDOP);


    /* Init output arguments */
    *p_dlg = NULL;
    if (p_tdata) *p_tdata = NULL;

    pj_list_init(&res_hdr_list);

    /* Find Replaces header */
    rep_hdr = (pjsip_replaces_hdr*) 
	      pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_REPLACES, 
					 NULL);
    if (!rep_hdr) {
	/* No Replaces header. No further processing is necessary. */
	return PJ_SUCCESS;
    }


    /* Check that there's no other Replaces header and return 400 Bad Request
     * if not. 
     */
    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &STR_REPLACES, 
				   rep_hdr->next)) {
	code = PJSIP_SC_BAD_REQUEST;
	warn_text = "Found multiple Replaces headers";
	goto on_return;
    }

    /* Find the dialog identified by Replaces header (and always lock the
     * dialog no matter what application wants).
     */
    dlg = pjsip_ua_find_dialog(&rep_hdr->call_id, &rep_hdr->to_tag,
			       &rep_hdr->from_tag, PJ_TRUE);

    /* Respond with 481 "Call/Transaction Does Not Exist" response if
     * no dialog is found.
     */
    if (dlg == NULL) {
	code = PJSIP_SC_CALL_TSX_DOES_NOT_EXIST;
	warn_text = "No dialog found for Replaces request";
	goto on_return;
    }

    /* Get the invite session within the dialog */
    inv = pjsip_dlg_get_inv_session(dlg);

    /* Return 481 if no invite session is present. */
    if (inv == NULL) {
	code = PJSIP_SC_CALL_TSX_DOES_NOT_EXIST;
	warn_text = "No INVITE session found for Replaces request";
	goto on_return;
    }

    /* Return 603 Declined response if invite session has already 
     * terminated 
     */
    if (inv->state >= PJSIP_INV_STATE_DISCONNECTED) {
	code = PJSIP_SC_DECLINE;
	warn_text = "INVITE session already terminated";
	goto on_return;
    }

    /* If "early-only" flag is present, check that the invite session
     * has not been confirmed yet. If the session has been confirmed, 
     * return 486 "Busy Here" response.
     */
    if (rep_hdr->early_only && inv->state >= PJSIP_INV_STATE_CONNECTING) {
	code = PJSIP_SC_BUSY_HERE;
	warn_text = "INVITE session already established";
	goto on_return;
    }

    /* If the Replaces header field matches an early dialog that was not
     * initiated by this UA, it returns a 481 (Call/Transaction Does Not
     * Exist) response to the new INVITE.
     */
    if (inv->state <= PJSIP_INV_STATE_EARLY && inv->role != PJSIP_ROLE_UAC) {
	code = PJSIP_SC_CALL_TSX_DOES_NOT_EXIST;
	warn_text = "Found early INVITE session but not initiated by this UA";
	goto on_return;
    }


    /*
     * Looks like everything is okay!!
     */
    *p_dlg = dlg;
    status = PJ_SUCCESS;
    code = 200;

on_return:

    /* Create response if necessary */
    if (code != 200) {
	/* If we have dialog we must unlock it */
	if (dlg)
	    pjsip_dlg_dec_lock(dlg);

	/* Create response */
	if (p_tdata) {
	    pjsip_tx_data *tdata;
	    const pjsip_hdr *h;

	    status = pjsip_endpt_create_response(the_endpt, rdata, code, 
						 NULL, &tdata);

	    if (status != PJ_SUCCESS)
		return status;

	    /* Add response headers. */
	    h = res_hdr_list.next;
	    while (h != &res_hdr_list) {
		pjsip_hdr *cloned;

		cloned = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, h);
		PJ_ASSERT_RETURN(cloned, PJ_ENOMEM);

		pjsip_msg_add_hdr(tdata->msg, cloned);

		h = h->next;
	    }

	    /* Add warn text, if any */
	    if (warn_text) {
		pjsip_warning_hdr *warn_hdr;
		pj_str_t warn_value = pj_str((char*)warn_text);

		warn_hdr=pjsip_warning_hdr_create(tdata->pool, 399, 
						  pjsip_endpt_name(the_endpt),
						  &warn_value);
		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)warn_hdr);
	    }

	    *p_tdata = tdata;
	}

	/* Can not return PJ_SUCCESS when response message is produced.
	 * Ref: PROTOS test ~#2490
	 */
	if (status == PJ_SUCCESS)
	    status = PJSIP_ERRNO_FROM_SIP_STATUS(code);

    } else {
	/* If application doesn't want to lock the dialog, unlock it */
	if (!lock_dlg)
	    pjsip_dlg_dec_lock(dlg);
    }

    return status;
}



