/*
 * OBEX Server
 *
 * Copyright (C) 2008-2010 Intel Corporation.  All rights reserved.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <errno.h>

#include <glib.h>
#include <gdbus/gdbus.h>

#include "vcard.h"

#define ADDR_FIELD_AMOUNT 7
#define LEN_MAX 128
#define TYPE_INTERNATIONAL 145

#define PHONEBOOK_FLAG_CACHED 0x1

#define FILTER_VERSION (1 << 0)
#define FILTER_FN (1 << 1)
#define FILTER_N (1 << 2)
#define FILTER_PHOTO (1 << 3)
#define FILTER_BDAY (1 << 4)
#define FILTER_ADR (1 << 5)
#define FILTER_LABEL (1 << 6)
#define FILTER_TEL (1 << 7)
#define FILTER_EMAIL (1 << 8)
#define FILTER_MAILER (1 << 9)
#define FILTER_TZ (1 << 10)
#define FILTER_GEO (1 << 11)
#define FILTER_TITLE (1 << 12)
#define FILTER_ROLE (1 << 13)
#define FILTER_LOGO (1 << 14)
#define FILTER_AGENT (1 << 15)
#define FILTER_ORG (1 << 16)
#define FILTER_NOTE (1 << 17)
#define FILTER_REV (1 << 18)
#define FILTER_SOUND (1 << 19)
#define FILTER_URL (1 << 20)
#define FILTER_UID (1 << 21)
#define FILTER_KEY (1 << 22)
#define FILTER_NICKNAME (1 << 23)
#define FILTER_CATEGORIES (1 << 24)
#define FILTER_PROID (1 << 25)
#define FILTER_CLASS (1 << 26)
#define FILTER_SORT_STRING (1 << 27)
#define FILTER_X_IRMC_CALL_DATETIME (1 << 28)

#define FORMAT_VCARD21 0x00
#define FORMAT_VCARD30 0x01

#define QP_LINE_LEN 75
#define QP_CHAR_LEN 3
#define QP_CR 0x0D
#define QP_LF 0x0A
#define QP_ESC 0x5C
#define QP_SOFT_LINE_BREAK "="
#define QP_SELECT "\n!\"#$=@[\\]^`{|}~"
#define ASCII_LIMIT 0x7F

/* according to RFC 2425, the output string may need folding */
static void vcard_printf(GString *str, const char *fmt, ...)
{
	char buf[1024];
	va_list ap;
	int len_temp, line_number, i;
	unsigned int line_delimit = 75;

	va_start(ap, fmt);
	vsnprintf(buf, sizeof(buf), fmt, ap);
	va_end(ap);

	line_number = strlen(buf) / line_delimit + 1;

	for (i = 0; i < line_number; i++) {
		len_temp = MIN(line_delimit, strlen(buf) - line_delimit * i);
		g_string_append_len(str,  buf + line_delimit * i, len_temp);
		if (i != line_number - 1)
			g_string_append(str, "\r\n ");
	}

	g_string_append(str, "\r\n");
}

/* According to RFC 2426, we need escape following characters:
 *  '\n', '\r', ';', ',', '\'.
 */
static void add_slash(char *dest, const char *src, int len_max, int len)
{
	int i, j;

	for (i = 0, j = 0; i < len && j + 1 < len_max; i++, j++) {
		/* filling dest buffer - last field need to be reserved
		 * for '\0'*/
		switch (src[i]) {
		case '\n':
			if (j + 2 >= len_max)
				/* not enough space in the buffer to put char
				 * preceded with escaping sequence (and '\0' in
				 * the end) */
				goto done;

			dest[j++] = '\\';
			dest[j] = 'n';
			break;
		case '\r':
			if (j + 2 >= len_max)
				goto done;

			dest[j++] = '\\';
			dest[j] = 'r';
			break;
		case '\\':
		case ';':
		case ',':
			if (j + 2 >= len_max)
				goto done;

			dest[j++] = '\\';
		default:
			dest[j] = src[i];
			break;
		}
	}

done:
	dest[j] = 0;
}

static void escape_semicolon(char *dest, const char *src, int len_max, int len)
{
	int i, j;

	for (i = 0, j = 0; i < len && j + 1 < len_max; i++, j++) {
		if (src[i] == ';') {
			if (j + 2 >= len_max)
				break;

			dest[j++] = '\\';
		}

		dest[j] = src[i];
	}

	dest[j] = 0;
}

static void set_escape(uint8_t format, char *dest, const char *src,
							int len_max, int len)
{
	if (format == FORMAT_VCARD30)
		add_slash(dest, src, len_max, len);
	else if (format == FORMAT_VCARD21)
		escape_semicolon(dest, src, len_max, len);
}

static void get_escaped_fields(uint8_t format, char **fields, ...)
{
	va_list ap;
	GString *line;
	char *field;
	char escaped[LEN_MAX];

	va_start(ap, fields);
	line = g_string_new("");

	for (field = va_arg(ap, char *); field; ) {
		set_escape(format, escaped, field, LEN_MAX, strlen(field));
		g_string_append(line, escaped);

		field = va_arg(ap, char *);

		if (field)
			g_string_append(line, ";");
	}

	va_end(ap);

	*fields = g_string_free(line, FALSE);
}

static gboolean set_qp_encoding(char c)
{
	unsigned char q = c;

	if (strchr(QP_SELECT, q) != NULL)
		return TRUE;

	if (q < '!' || q > '~')
		return TRUE;

	return FALSE;
}

static void append_qp_break_line(GString *vcards, size_t *limit)
{
	/* Quoted Printable lines of text must be limited to less than 76
	 * characters and terminated by Quoted Printable softline break
	 * sequence of "=" (if some more characters left) */
	g_string_append(vcards, QP_SOFT_LINE_BREAK);
	g_string_append(vcards, "\r\n ");
	*limit = QP_LINE_LEN - 1;
}

static void append_qp_ascii(GString *vcards, size_t *limit, char c)
{
	if (*limit == 0)
		append_qp_break_line(vcards, limit);

	g_string_append_c(vcards, c);
	--*limit;
}

static void append_qp_hex(GString *vcards, size_t *limit, char c)
{
	if (*limit < QP_CHAR_LEN)
		append_qp_break_line(vcards, limit);

	g_string_append_printf(vcards, "=%2.2X", (unsigned char) c);
	*limit -= QP_CHAR_LEN;
}

static void append_qp_new_line(GString *vcards, size_t *limit)
{
	/* Multiple lines of text are separated with a Quoted Printable CRLF
	 * sequence of "=0D" followed by "=0A" followed by a Quoted Printable
	 * softline break sequence of "=" */
	append_qp_hex(vcards, limit, QP_CR);
	append_qp_hex(vcards, limit, QP_LF);
	append_qp_break_line(vcards, limit);
}

static gboolean utf8_select(const char *field)
{
	const char *pos;

	if (g_utf8_validate(field, -1, NULL) == FALSE)
		return FALSE;

	for (pos = field; *pos != '\0'; pos = g_utf8_next_char(pos)) {
		/* Test for non-standard UTF-8 character (out of range
		 * standard ASCII set), composed of more than single byte
		 * and represented by 32-bit value greater than 0x7F */
		if (g_utf8_get_char(pos) > ASCII_LIMIT)
			return TRUE;
	}

	return FALSE;
}

static void vcard_qp_print_encoded(GString *vcards, const char *desc, ...)
{
	const char *field, *charset = "";
	const char *encoding = ";ENCODING=QUOTED-PRINTABLE";
	size_t limit, param_len;
	va_list ap;

	va_start(ap, desc);

	for (field = va_arg(ap, char *); field; field = va_arg(ap, char *)) {
		if (utf8_select(field) == TRUE) {
			charset = ";CHARSET=UTF-8";
			break;
		}
	}

	va_end(ap);

	vcard_printf(vcards, "%s%s%s:", desc, encoding, charset);
	g_string_truncate(vcards, vcards->len - 2);

	param_len = strlen(desc) + strlen(encoding) + strlen(charset) + 1;
	limit = QP_LINE_LEN - param_len;

	va_start(ap, desc);

	for (field = va_arg(ap, char *); field != NULL; ) {
		size_t i, size = strlen(field);

		for (i = 0; i < size; ++i) {
			if (set_qp_encoding(field[i])) {
				if (field[i] == '\n') {
					append_qp_new_line(vcards, &limit);
					continue;
				}

				append_qp_hex(vcards, &limit, field[i]);
			} else {
				/* According to vCard 2.1 spec. semicolons in
				 * property parameter value must be escaped */
				if (field[i] == ';')
					append_qp_hex(vcards, &limit, QP_ESC);

				append_qp_ascii(vcards, &limit, field[i]);
			}
		}

		field = va_arg(ap, char *);
		if (field)
			append_qp_ascii(vcards, &limit, ';');
	}

	va_end(ap);

	g_string_append(vcards, "\r\n");
}

static gboolean select_qp_encoding(uint8_t format, ...)
{
	char *field;
	va_list ap;

	if (format != FORMAT_VCARD21)
		return FALSE;

	va_start(ap, format);

	for (field = va_arg(ap, char *); field; field = va_arg(ap, char *)) {
		int i;
		unsigned char c;

		if (strpbrk(field, QP_SELECT)) {
			va_end(ap);
			return TRUE;
		}

		/* Quoted Printable encoding is selected if there is
		 * a character, which value is out of range standard
		 * ASCII set, since it may be a part of some
		 * non-standard character such as specified by UTF-8 */
		for (i = 0; (c = field[i]) != '\0'; ++i) {
			if (c > ASCII_LIMIT) {
				va_end(ap);
				return TRUE;
			}
		}
	}

	va_end(ap);

	return FALSE;
}

static void vcard_printf_begin(GString *vcards, uint8_t format)
{
	vcard_printf(vcards, "BEGIN:VCARD");

	if (format == FORMAT_VCARD30)
		vcard_printf(vcards, "VERSION:3.0");
	else if (format == FORMAT_VCARD21)
		vcard_printf(vcards, "VERSION:2.1");
}

/* check if there is at least one contact field with personal data present */
static gboolean contact_fields_present(struct phonebook_contact * contact)
{
	if (contact->family && strlen(contact->family) > 0)
		return TRUE;

	if (contact->given && strlen(contact->given) > 0)
		return TRUE;

	if (contact->additional && strlen(contact->additional) > 0)
		return TRUE;

	if (contact->prefix && strlen(contact->prefix) > 0)
		return TRUE;

	if (contact->suffix && strlen(contact->suffix) > 0)
		return TRUE;

	/* none of the personal data fields are present*/
	return FALSE;
}

static void vcard_printf_name(GString *vcards, uint8_t format,
					struct phonebook_contact *contact)
{
	char *fields;

	if (contact_fields_present(contact) == FALSE) {
		/* If fields are empty, add only 'N:' as parameter.
		 * This is crucial for some devices (Nokia BH-903) which
		 * have problems with history listings and can't determine
		 * that a parameter is really empty if there are unnecessary
		 * characters after 'N:' (e.g. 'N:;;;;').
		 * We need to add only'N:' param - without semicolons.
		 */
		vcard_printf(vcards, "N:");
		return;
	}

	if (select_qp_encoding(format, contact->family, contact->given,
					contact->additional, contact->prefix,
					contact->suffix, NULL)) {
		vcard_qp_print_encoded(vcards, "N", contact->family,
					contact->given, contact->additional,
					contact->prefix, contact->suffix,
					NULL);
		return;
	}

	get_escaped_fields(format, &fields, contact->family,
				contact->given, contact->additional,
				contact->prefix, contact->suffix,
				NULL);

	vcard_printf(vcards, "N:%s", fields);

	g_free(fields);
}

static void vcard_printf_fullname(GString *vcards, uint8_t format,
							const char *text)
{
	char field[LEN_MAX];

	if (!text || strlen(text) == 0) {
		vcard_printf(vcards, "FN:");
		return;
	}

	if (select_qp_encoding(format, text, NULL)) {
		vcard_qp_print_encoded(vcards, "FN", text, NULL);
		return;
	}

	set_escape(format, field, text, LEN_MAX, strlen(text));
	vcard_printf(vcards, "FN:%s", field);
}

static void vcard_printf_number(GString *vcards, uint8_t format,
					const char *number, int type,
					enum phonebook_number_type category)
{
	const char *intl = "", *category_string = "";
	char buf[LEN_MAX], field[LEN_MAX];

	/* TEL is a mandatory field, include even if empty */
	if (!number || !strlen(number) || !type) {
		vcard_printf(vcards, "TEL:");
		return;
	}

	switch (category) {
	case TEL_TYPE_HOME:
		if (format == FORMAT_VCARD21)
			category_string = "HOME;VOICE";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=HOME;TYPE=VOICE";
		break;
	case TEL_TYPE_MOBILE:
		if (format == FORMAT_VCARD21)
			category_string = "CELL;VOICE";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=CELL;TYPE=VOICE";
		break;
	case TEL_TYPE_FAX:
		if (format == FORMAT_VCARD21)
			category_string = "FAX";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=FAX";
		break;
	case TEL_TYPE_WORK:
		if (format == FORMAT_VCARD21)
			category_string = "WORK;VOICE";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=WORK;TYPE=VOICE";
		break;
	case TEL_TYPE_OTHER:
		if (format == FORMAT_VCARD21)
			category_string = "OTHER;VOICE";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=OTHER;TYPE=VOICE";
		break;
	}

	if ((type == TYPE_INTERNATIONAL) && (number[0] != '+'))
		intl = "+";

	snprintf(field, sizeof(field), "%s%s", intl, number);

	if (select_qp_encoding(format, number, NULL)) {
		snprintf(buf, sizeof(buf), "TEL;%s", category_string);
		vcard_qp_print_encoded(vcards, buf, field, NULL);
		return;
	}

	vcard_printf(vcards, "TEL;%s:%s", category_string, field);
}

static void vcard_printf_tag(GString *vcards, uint8_t format,
					const char *tag, const char *category,
					const char *fld)
{
	int len;
	char *separator = "", *type = "";
	char buf[LEN_MAX], field[LEN_MAX];

	if (tag == NULL || strlen(tag) == 0)
		return;

	if (fld == NULL || (len = strlen(fld)) == 0) {
		vcard_printf(vcards, "%s:", tag);
		return;
	}

	if (category && strlen(category)) {
		separator = ";";
		if (format == FORMAT_VCARD30)
			type = "TYPE=";
	} else {
		category = "";
	}

	snprintf(buf, LEN_MAX, "%s%s%s%s", tag, separator, type, category);

	if (select_qp_encoding(format, fld, NULL)) {
		vcard_qp_print_encoded(vcards, buf, fld, NULL);
		return;
	}

	set_escape(format, field, fld, LEN_MAX, len);
	vcard_printf(vcards, "%s:%s", buf, field);
}

static void vcard_printf_email(GString *vcards, uint8_t format,
					const char *address,
					enum phonebook_field_type category)
{
	const char *category_string = "";
	char buf[LEN_MAX], field[LEN_MAX];
	int len = 0;

	if (!address || !(len = strlen(address))) {
		vcard_printf(vcards, "EMAIL:");
		return;
	}
	switch (category) {
	case FIELD_TYPE_HOME:
		if (format == FORMAT_VCARD21)
			category_string = "INTERNET;HOME";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=INTERNET;TYPE=HOME";
		break;
	case FIELD_TYPE_WORK:
		if (format == FORMAT_VCARD21)
			category_string = "INTERNET;WORK";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=INTERNET;TYPE=WORK";
		break;
	default:
		if (format == FORMAT_VCARD21)
			category_string = "INTERNET";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=INTERNET;TYPE=OTHER";
	}

	if (select_qp_encoding(format, address, NULL)) {
		snprintf(buf, sizeof(buf), "EMAIL;%s", category_string);
		vcard_qp_print_encoded(vcards, buf, address, NULL);
		return;
	}

	set_escape(format, field, address, LEN_MAX, len);
	vcard_printf(vcards, "EMAIL;%s:%s", category_string, field);
}

static void vcard_printf_url(GString *vcards, uint8_t format,
					const char *url,
					enum phonebook_field_type category)
{
	const char *category_string = "";
	char buf[LEN_MAX], field[LEN_MAX];

	if (!url || strlen(url) == 0) {
		vcard_printf(vcards, "URL:");
		return;
	}

	switch (category) {
	case FIELD_TYPE_HOME:
		if (format == FORMAT_VCARD21)
			category_string = "INTERNET;HOME";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=INTERNET;TYPE=HOME";
		break;
	case FIELD_TYPE_WORK:
		if (format == FORMAT_VCARD21)
			category_string = "INTERNET;WORK";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=INTERNET;TYPE=WORK";
		break;
	default:
		if (format == FORMAT_VCARD21)
			category_string = "INTERNET";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=INTERNET";
		break;
	}

	if (select_qp_encoding(format, url, NULL)) {
		snprintf(buf, sizeof(buf), "URL;%s", category_string);
		vcard_qp_print_encoded(vcards, buf, url, NULL);
		return;
	}

	set_escape(format, field, url, LEN_MAX, strlen(url));
	vcard_printf(vcards, "URL;%s:%s", category_string, field);
}

static gboolean org_fields_present(struct phonebook_contact *contact)
{
	if (contact->company && strlen(contact->company))
		return TRUE;

	if (contact->department && strlen(contact->department))
		return TRUE;

	return FALSE;
}

static void vcard_printf_org(GString *vcards, uint8_t format,
					struct phonebook_contact *contact)
{
	char *fields;

	if (org_fields_present(contact) == FALSE)
		return;

	if (select_qp_encoding(format, contact->company,
						contact->department, NULL)) {
		vcard_qp_print_encoded(vcards, "ORG", contact->company,
						contact->department, NULL);
		return;
	}

	get_escaped_fields(format, &fields, contact->company,
					contact->department, NULL);

	vcard_printf(vcards, "ORG:%s", fields);

	g_free(fields);
}

static void vcard_printf_address(GString *vcards, uint8_t format,
					struct phonebook_addr *address)
{
	char *fields, field_esc[LEN_MAX];
	const char *category_string = "";
	char buf[LEN_MAX], *address_fields[ADDR_FIELD_AMOUNT];
	int i;
	size_t len;
	GSList *l;

	if (!address) {
		vcard_printf(vcards, "ADR:");
		return;
	}

	switch (address->type) {
	case FIELD_TYPE_HOME:
		if (format == FORMAT_VCARD21)
			category_string = "HOME";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=HOME";
		break;
	case FIELD_TYPE_WORK:
		if (format == FORMAT_VCARD21)
			category_string = "WORK";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=WORK";
		break;
	default:
		if (format == FORMAT_VCARD21)
			category_string = "OTHER";
		else if (format == FORMAT_VCARD30)
			category_string = "TYPE=OTHER";
		break;
	}

	for (i = 0, l = address->fields; l; l = l->next)
		address_fields[i++] = l->data;

	if (select_qp_encoding(format, address_fields[0], address_fields[1],
					address_fields[2], address_fields[3],
					address_fields[4], address_fields[5],
					address_fields[6], NULL)) {
		snprintf(buf, sizeof(buf), "ADR;%s", category_string);
		vcard_qp_print_encoded(vcards, buf,
					address_fields[0], address_fields[1],
					address_fields[2], address_fields[3],
					address_fields[4], address_fields[5],
					address_fields[6], NULL);
		return;
	}

	/* allocate enough memory to insert address fields separated by ';'
	 * and terminated by '\0' */
	len = ADDR_FIELD_AMOUNT * LEN_MAX;
	fields = g_malloc0(len);

	for (l = address->fields; l; l = l->next) {
		char *field = l->data;

		if (field) {
			set_escape(format, field_esc, field, LEN_MAX,
								strlen(field));
			g_strlcat(fields, field_esc, len);
		}

		if (l->next)
			/* not adding ';' after last addr field */
			g_strlcat(fields, ";", len);
	}

	vcard_printf(vcards,"ADR;%s:%s", category_string, fields);

	g_free(fields);
}

static void vcard_printf_datetime(GString *vcards, uint8_t format,
					struct phonebook_contact *contact)
{
	const char *type;
	char buf[LEN_MAX];

	switch (contact->calltype) {
	case CALL_TYPE_MISSED:
		type = "MISSED";
		break;

	case CALL_TYPE_INCOMING:
		type = "RECEIVED";
		break;

	case CALL_TYPE_OUTGOING:
		type = "DIALED";
		break;

	case CALL_TYPE_NOT_A_CALL:
	default:
		return;
	}

	if (select_qp_encoding(format, contact->datetime, NULL)) {
		snprintf(buf, sizeof(buf), "X-IRMC-CALL-DATETIME;%s", type);
		vcard_qp_print_encoded(vcards, buf, contact->datetime, NULL);
		return;
	}

	vcard_printf(vcards, "X-IRMC-CALL-DATETIME;%s:%s", type,
							contact->datetime);
}

static void vcard_printf_end(GString *vcards)
{
	vcard_printf(vcards, "END:VCARD");
}

void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
					uint64_t filter, uint8_t format)
{
	if (format == FORMAT_VCARD30 && filter)
		filter |= (FILTER_VERSION | FILTER_FN | FILTER_N | FILTER_TEL);
	else if (format == FORMAT_VCARD21 && filter)
		filter |= (FILTER_VERSION | FILTER_N | FILTER_TEL);
	else
		filter = (FILTER_VERSION | FILTER_UID | FILTER_N | FILTER_FN |
				FILTER_TEL | FILTER_EMAIL | FILTER_ADR |
				FILTER_BDAY | FILTER_NICKNAME | FILTER_URL |
				FILTER_PHOTO | FILTER_ORG | FILTER_ROLE |
				FILTER_TITLE | FILTER_X_IRMC_CALL_DATETIME);

	vcard_printf_begin(vcards, format);

	if (filter & FILTER_UID && *contact->uid)
		vcard_printf_tag(vcards, format, "UID", NULL, contact->uid);

	if (filter & FILTER_N)
		vcard_printf_name(vcards, format, contact);

	if (filter & FILTER_FN && (*contact->fullname ||
					format == FORMAT_VCARD30))
		vcard_printf_fullname(vcards, format, contact->fullname);

	if (filter & FILTER_TEL) {
		GSList *l = contact->numbers;

		if (g_slist_length(l) == 0)
			vcard_printf_number(vcards, format, NULL, 1,
							TEL_TYPE_OTHER);

		for (; l; l = l->next) {
			struct phonebook_field *number = l->data;

			vcard_printf_number(vcards, format, number->text, 1,
								number->type);
		}
	}

	if (filter & FILTER_EMAIL) {
		GSList *l = contact->emails;

		for (; l; l = l->next) {
			struct phonebook_field *email = l->data;
			vcard_printf_email(vcards, format, email->text,
								email->type);
		}
	}

	if (filter & FILTER_ADR) {
		GSList *l = contact->addresses;

		for (; l; l = l->next) {
			struct phonebook_addr *addr = l->data;
			vcard_printf_address(vcards, format, addr);
		}
	}

	if (filter & FILTER_BDAY && *contact->birthday)
		vcard_printf_tag(vcards, format, "BDAY", NULL,
						contact->birthday);

	if (filter & FILTER_NICKNAME && *contact->nickname)
		vcard_printf_tag(vcards, format, "NICKNAME", NULL,
							contact->nickname);

	if (filter & FILTER_URL) {
		GSList *l = contact->urls;

		for (; l; l = l->next) {
			struct phonebook_field *url = l->data;
			vcard_printf_url(vcards, format, url->text, url->type);
		}
	}

	if (filter & FILTER_PHOTO && *contact->photo)
		vcard_printf_tag(vcards, format, "PHOTO", NULL,
							contact->photo);

	if (filter & FILTER_ORG)
		vcard_printf_org(vcards, format, contact);

	if (filter & FILTER_ROLE && *contact->role)
		vcard_printf_tag(vcards, format, "ROLE", NULL, contact->role);

	if (filter & FILTER_TITLE && *contact->title)
		vcard_printf_tag(vcards, format, "TITLE", NULL, contact->title);

	if (filter & FILTER_X_IRMC_CALL_DATETIME)
		vcard_printf_datetime(vcards, format, contact);

	vcard_printf_end(vcards);
}

static void field_free(gpointer data)
{
	struct phonebook_field *field = data;

	g_free(field->text);
	g_free(field);
}

void phonebook_addr_free(gpointer addr)
{
	struct phonebook_addr *address = addr;

	g_slist_free_full(address->fields, g_free);
	g_free(address);
}

void phonebook_contact_free(struct phonebook_contact *contact)
{
	if (contact == NULL)
		return;

	g_slist_free_full(contact->numbers, field_free);
	g_slist_free_full(contact->emails, field_free);
	g_slist_free_full(contact->addresses, phonebook_addr_free);
	g_slist_free_full(contact->urls, field_free);

	g_free(contact->uid);
	g_free(contact->fullname);
	g_free(contact->given);
	g_free(contact->family);
	g_free(contact->additional);
	g_free(contact->prefix);
	g_free(contact->suffix);
	g_free(contact->birthday);
	g_free(contact->nickname);
	g_free(contact->photo);
	g_free(contact->company);
	g_free(contact->department);
	g_free(contact->role);
	g_free(contact->title);
	g_free(contact->datetime);
	g_free(contact);
}
