/*
 * Copyright (C) 2012 Andrew Mortensen
 *
 * This file is part of the sca module for Kamailio, a free SIP server.
 *
 * The sca module 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
 *
 * The sca module 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., 51 Franklin Street, Fifth Floor, Boston, MA. 02110-1301 USA
 */
#include "sca_common.h"

#include <assert.h>

#include "sca_dialog.h"

int sca_dialog_build_from_tags(sca_dialog *dialog, int maxlen, str *call_id,
		str *from_tag, str *to_tag)
{
	int len = 0;

	assert(dialog != NULL && dialog->id.s != NULL);
	assert(call_id != NULL);
	assert(from_tag != NULL);

	LM_DBG("From-Tag: %.*s To-Tag: %.*s CallId: %.*s\n", STR_FMT(from_tag),
			STR_FMT(to_tag), STR_FMT(call_id));

	len = call_id->len + from_tag->len;
	if(!SCA_STR_EMPTY(to_tag)) {
		len += to_tag->len;
	}

	if(len >= maxlen) {
		LM_ERR("sca_dialog_build_from_tags: tags too long\n");
		return (-1);
	}

	memcpy(dialog->id.s, call_id->s, call_id->len);
	dialog->call_id.s = dialog->id.s;
	dialog->call_id.len = call_id->len;

	memcpy(dialog->id.s + call_id->len, from_tag->s, from_tag->len);
	dialog->from_tag.s = dialog->id.s + call_id->len;
	dialog->from_tag.len = from_tag->len;

	if(!SCA_STR_EMPTY(to_tag)) {
		memcpy(dialog->id.s + call_id->len + from_tag->len, to_tag->s,
				to_tag->len);
		dialog->to_tag.s = dialog->id.s + call_id->len + from_tag->len;
		dialog->to_tag.len = to_tag->len;
	}
	dialog->id.len = len;

	return (len);
}

#define SCA_REPLACES_HDR_PREFIX "Replaces: "
#define SCA_REPLACES_HDR_PREFIX_LEN strlen(SCA_REPLACES_HDR_PREFIX)
#define SCA_REPLACES_TO_TAG "to-tag="
#define SCA_REPLACES_TO_TAG_LEN strlen(SCA_REPLACES_TO_TAG)
#define SCA_REPLACES_FROM_TAG "from-tag="
#define SCA_REPLACES_FROM_TAG_LEN strlen(SCA_REPLACES_FROM_TAG)

int sca_dialog_create_replaces_header(sca_dialog *dlg, str *replaces_hdr)
{
	int len;

	assert(replaces_hdr != NULL);

	LM_DBG("Called\n");

	if(SCA_STR_EMPTY(&dlg->call_id) || SCA_STR_EMPTY(&dlg->from_tag)
			|| SCA_STR_EMPTY(&dlg->to_tag)) {
		LM_ERR("sca_dialog_create_replaces_header: dialog %.*s is not a "
			   "confirmed dialog, cannot build Replaces header\n",
				STR_FMT(&dlg->id));
		return (-1);
	}

	memset(replaces_hdr, 0, sizeof(str));

	// +2 for semicolons separating tags, +2 for CRLF
	replaces_hdr->s =
			pkg_malloc(SCA_REPLACES_HDR_PREFIX_LEN + SCA_REPLACES_TO_TAG_LEN
					   + SCA_REPLACES_FROM_TAG_LEN + dlg->id.len + 2 + 2);

	memcpy(replaces_hdr->s, SCA_REPLACES_HDR_PREFIX,
			SCA_REPLACES_HDR_PREFIX_LEN);
	len = SCA_REPLACES_HDR_PREFIX_LEN;

	memcpy(replaces_hdr->s + len, dlg->call_id.s, dlg->call_id.len);
	len += dlg->call_id.len;

	memcpy(replaces_hdr->s + len, ";", strlen(";"));
	len += strlen(";");

	memcpy(replaces_hdr->s + len, SCA_REPLACES_TO_TAG, SCA_REPLACES_TO_TAG_LEN);
	len += SCA_REPLACES_TO_TAG_LEN;
	memcpy(replaces_hdr->s + len, dlg->to_tag.s, dlg->to_tag.len);
	len += dlg->to_tag.len;

	memcpy(replaces_hdr->s + len, ";", strlen(";"));
	len += strlen(";");

	memcpy(replaces_hdr->s + len, SCA_REPLACES_FROM_TAG,
			SCA_REPLACES_FROM_TAG_LEN);
	len += SCA_REPLACES_FROM_TAG_LEN;
	memcpy(replaces_hdr->s + len, dlg->from_tag.s, dlg->from_tag.len);
	len += dlg->from_tag.len;

	memcpy(replaces_hdr->s + len, CRLF, CRLF_LEN);
	len += CRLF_LEN;

	replaces_hdr->len = len;

	return (len);
}
