/*
 * 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++] = '\\';
			/* fall through */
		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;
	case FIELD_TYPE_OTHER:
	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;
	case FIELD_TYPE_OTHER:
	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);
}
