/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
 * test_util.c
 *
 *  Created on: Sep 30, 2010
 *      Author: Peter Neuhaus <p.neuhaus@tarent.de>,
 *      		Hendrik Helwich <h.helwich@tarent.de>,
 *      		Andreas Grau <a.grau@tarent.de>
 */
/*
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 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 Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser 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 <time.h>
#include "test-util.h"
#include "../../main/src/logging.h"
#include "testbase.h"
#include <gmime/gmime.h>
#include <string.h>
#include <kolab-conv.h>
#include <libxml/tree.h>	/* XML parsing */

void
assert_equal(gchar *expected, GString *value)
{
	GString *expected_str = NULL;

	g_debug("testing if string value '%s' is equal to expected value '%s'", value ? value->str : NULL, expected);
	if (expected == NULL) {
		g_assert(value == NULL);
		return;
	}
	g_assert(value != NULL);
	expected_str = g_string_new(expected);
	g_assert(g_string_equal(expected_str, value));
	g_string_free(expected_str, TRUE);
}

void
assert_equal_gchar(gchar *expected, gchar *value)
{
	g_debug("testing if string value '%s' is equal to expected value '%s'", value, expected);
	if (expected == NULL) {
		g_assert(value == NULL);
		return;
	}
	g_assert(value != NULL);
	g_assert(strcmp(expected, value) == 0);
}

void
assert_equal_int (gint expected, gint value)
{
	g_debug("testing if int value '%i' is equal to expected value '%i'", value, expected);
	g_assert(value == expected);
}

void
assert_equal_double (gdouble expected, gdouble value)
{
	g_debug("testing if double value '%f' is equal to expected value '%f'", value, expected);
	g_assert(value == expected);
}

void
assert_equal_gdate(gchar *expected, GDate *gdate)
{
	gchar *gstr = NULL;
	GString *gstr_new = NULL;

	if (expected == NULL) {
		g_assert(gdate == NULL);
		return;
	}

	gstr = g_strdup_printf("%04d-%02d-%02d",
	                       g_date_get_year (gdate),
	                       g_date_get_month (gdate),
	                       g_date_get_day (gdate));

	gstr_new = g_string_new(gstr);
	assert_equal(expected, gstr_new);

	g_free(gstr);
	g_string_free(gstr_new, TRUE);
}

void
assert_equal_timestamp(gchar *expected, time_t *timestamp)
{
	struct tm *ts = NULL;
	gchar *tstr = NULL;

	g_debug("timestamp: %lu", *timestamp);

	ts = gmtime(timestamp);

	tstr = g_strdup_printf("%04d-%02d-%02d %02d:%02d:%02d",
	                       ts->tm_year + 1900,
	                       ts->tm_mon + 1,
	                       ts->tm_mday,
	                       ts->tm_hour,
	                       ts->tm_min,
	                       ts->tm_sec);

	g_debug("testing if string value '%s' is equal to expected value '%s'", tstr, expected);

	g_assert(strcmp(expected, tstr) == 0);

	g_free(tstr);
}

void
assert_timestamp_not_older_than_10_seconds(time_t *timestamp)
{
	time_t now = NULL;

	g_debug("timestamp: %lu", *timestamp);

	now = time(NULL);

	g_assert(*timestamp <= now);

	g_assert(*timestamp >= (now-10));
}

/**
 * tests whether type/phone is in phone list.
 * searches for matching type and then compares numbers.
 */
Phone_number*
assert_phone_in_list (GList *phone_nrs, gchar *nr_expected, Icontact_phone_type type_expected)
{
	gint found_type = 0; /* type found? */
	gint matched_number = 0; /* numbers match? */
	Phone_number *ret = NULL;

	g_assert (phone_nrs != NULL);

	while (phone_nrs != NULL) {
		Phone_number *p = phone_nrs->data;

		g_assert (p != NULL);
		if (p != NULL) {
			g_debug ("testing if type '%d' matches expected type '%d'", p->type, type_expected);

			if (p->type == type_expected) {
				found_type = 1; /* types match */
				g_debug ("matching type '%d' found", type_expected);
				g_debug ("testing if number '%s' is equal to expected number '%s'",
				         p->number, nr_expected ? nr_expected : NULL);
				g_assert (p->number != NULL);
				g_assert (nr_expected != NULL);

				if (strcmp (p->number, nr_expected) == 0) {
					g_debug ("matching number '%s' found", nr_expected);
					matched_number = 1;
					ret = p;
					break;
				}
			}
		}

		phone_nrs = phone_nrs->next;
	}

	g_assert (found_type);
	g_assert (matched_number);
	return ret;
}

void
assert_list_null(GList *value) {

	g_debug("testing if given list is NULL");
	g_assert(value == NULL);
}

void
assert_list_length(GList *value, gint lenght_exp) {
	g_debug("list length: %i, expected: %i", g_list_length(value), lenght_exp);
	g_assert(g_list_length(value) == lenght_exp);
}

/**
 * tests whether email-address is in email list.
 * TODO: handle incongruent fields
 */
Email*
assert_email_in_list (GList *emails, gchar *smtp_address_exp, gchar *display_name_exp)
{
	Email *ret = NULL;

	g_assert (emails != NULL);

	while (emails != NULL) {
		Email *e = emails->data;

		gint matched_display_name = 0;
		gint matched_smtp_address = 0;

		g_assert (e != NULL);

		/* assert display_name */
		if (display_name_exp == NULL) {
			g_assert(e->display_name == NULL);
			matched_display_name = 1;
		}
		else if (strcmp(e->display_name->str, display_name_exp) == 0){
			matched_display_name = 1;
		}

		/* assert smtp_address */
		if (smtp_address_exp == NULL) {
			g_assert(e->smtp_address == NULL);
			matched_smtp_address = 1;
		}
		else if (strcmp(e->smtp_address->str, smtp_address_exp) == 0) {
			matched_smtp_address = 1;
		}

		if (matched_display_name == 1 && matched_smtp_address == 1) {
			ret = e;
			return ret;
		}

		emails = emails->next;
	}

	g_debug ("no matching email found in list");
	g_assert_not_reached();
}

Address*
assert_address_in_list (GList *addresses,
                        Icontact_address_type type,
                        gchar *street,
                        gchar *pobox,
                        gchar *locality,
                        gchar *region,
                        gchar *postal_code,
                        gchar *country)
{
	(void)type;

	g_assert (addresses != NULL);

	while (addresses != NULL) {
		Address *addr = addresses->data;

		gint matched_street = 0;
		gint matched_pobox = 0;
		gint matched_locality = 0;
		gint matched_region = 0;
		gint matched_postal_code = 0;
		gint matched_country = 0;

		g_assert (addr != NULL);

		/* street */
		if (street == NULL) {
			if(addr->street == NULL) {
				matched_street = 1;
			}
		}
		else if (strcmp(addr->street->str, street) == 0){
			matched_street = 1;
		}
		/* pobox */
		if (pobox == NULL) {
			if(addr->pobox == NULL) {
				matched_pobox = 1;
			}
		}
		else if (strcmp(addr->pobox->str, pobox) == 0){
			matched_pobox = 1;
		}
		/* locality */
		if (locality == NULL) {
			if(addr->locality == NULL) {
				matched_locality = 1;
			}
		}
		else if (strcmp(addr->locality->str, locality) == 0){
			matched_locality = 1;
		}
		/* region */
		if (region == NULL) {
			if(addr->region == NULL) {
				matched_region = 1;
			}
		}
		else if (strcmp(addr->region->str, region) == 0){
			matched_region = 1;
		}
		/* postal_code */
		if (postal_code == NULL) {
			if(addr->postal_code == NULL) {
				matched_postal_code = 1;
			}
		}
		else if (strcmp(addr->postal_code->str, postal_code) == 0){
			matched_postal_code = 1;
		}
		/* country */
		if (street == NULL) {
			if(addr->country == NULL) {
				matched_country = 1;
			}
		}
		else if (strcmp(addr->country->str, country) == 0){
			matched_country = 1;
		}

		if (matched_street == 1
		    && matched_pobox == 1
		    && matched_locality == 1
		    && matched_region == 1
		    && matched_postal_code == 1
		    && matched_country == 1) {
			return addr;
		}

		addresses = addresses->next;
	}
	g_debug ("no matching address found in list");
	g_assert_not_reached();
}

Alarm*
assert_Alarm_in_list (GList *advancedAlarm, Alarm_type type, gint start_offset, gint end_offset,
                      gint repeat_count, gint repeat_interval, gchar *display_text, gchar *audio_file,
                      gchar *proc_param_program, gchar *proc_param_arguments,
                      gchar *email_param_subject, gchar *email_param_mail_text)
{
	if (advancedAlarm != NULL) {	/* evolution tasks have no advanced_alarm */
		while (advancedAlarm != NULL) {
			Alarm *alarm = advancedAlarm->data;
			gint failed = 0; /* bitmap for error location */
			char *bm = NULL;

			g_assert (alarm != NULL);

			g_debug ("advancedAlarm values: "
			         "AlarmType: %i, "
			         "start_offset: %i, "
			         "end_offset: %i, "
			         "repeat_count: %i, "
			         "repeat_interval: %i, "
			         "display_text: '%s', "
			         "audio_file: '%s', "
			         "proc_param_program: '%s', "
			         "proc_param_arguments: '%s', "
			         "email_param_subject: '%s', "
			         "email_param_mail_text: '%s'",
			         alarm->type, alarm->start_offset, alarm->end_offset, alarm->repeat_count,
			         alarm->repeat_interval, alarm->display_text ? alarm->display_text->str : "NULL",
			         alarm->audio_file ? alarm->audio_file->str : "NULL",
			         alarm->proc_param && alarm->proc_param->program ? alarm->proc_param->program->str : "NULL",
			         alarm->proc_param && alarm->proc_param->arguments ? alarm->proc_param->arguments->str : "NULL",
			         alarm->email_param && alarm->email_param->subject ? alarm->email_param->subject->str : "NULL",
			         alarm->email_param && alarm->email_param->mail_text ? alarm->email_param->mail_text->str : "NULL");

			CHECK_FAILED(alarm->type == type, failed, 1);
			CHECK_FAILED(alarm->start_offset == start_offset, failed, 2);
			CHECK_FAILED(alarm->end_offset == end_offset, failed, 3);
			CHECK_FAILED(alarm->repeat_count == repeat_count, failed, 4);
			CHECK_FAILED(alarm->repeat_interval == repeat_interval, failed, 5);
			CHECK_FAILED(display_text == NULL || strcmp(alarm->display_text->str, display_text) == 0, failed, 6);
			CHECK_FAILED(audio_file == NULL || strcmp(alarm->audio_file->str, audio_file) == 0, failed, 7);
			CHECK_FAILED(proc_param_program == NULL || strcmp(alarm->proc_param->program->str, proc_param_program) == 0, failed, 8);
			CHECK_FAILED(proc_param_arguments == NULL || strcmp(alarm->proc_param->arguments->str, proc_param_arguments) == 0, failed, 9);
			/* email_param addresses list - own function assert_String_in_list() */
			CHECK_FAILED(email_param_subject == NULL || strcmp(alarm->email_param->subject->str, email_param_subject) == 0, failed, 10);
			CHECK_FAILED(email_param_mail_text == NULL || strcmp(alarm->email_param->mail_text->str, email_param_mail_text) == 0, failed, 11);
			/* email_param attachments list - own function assert_String_in_list() */

			bm = int_to_bitmask(failed);
			g_debug ("checks for alarm: %s", bm);
			g_free(bm);

			if (!failed)
				return alarm;

			advancedAlarm = advancedAlarm->next;
		}

		g_debug ("no matching alarm found in list");
		g_assert_not_reached();
	}

	return NULL;
}

void
assert_attendee_in_list(GList *attendees, gchar *display_name, gchar *smtp_address, Incidence_status status,
                        gboolean request_response, gboolean invitation_sent, Incidence_role role, Incidence_cutype type)
{
	while (attendees != NULL) {
		Attendee *attendee = attendees->data;
		g_assert (attendee != NULL);
		if (strcmp(attendee->smtp_address->str, smtp_address) == 0) {
			if (display_name)
				g_assert_cmpstr(attendee->display_name->str, ==, display_name);
			else
				g_assert(attendee->display_name == NULL);
			g_assert_cmpint(attendee->status, ==, status);
			g_assert_cmpint(attendee->request_response, ==, request_response);
			if (attendee->invitation_sent)
				g_assert_cmpint(attendee->invitation_sent, ==, invitation_sent);
			g_assert_cmpint(attendee->role, ==, role);
			g_assert_cmpint(attendee->cutype, ==, type);
			return;
		}
		attendees = attendees->next;
	}
	g_assert_not_reached();
}

void
assert_GDate_in_list(GList *date_list, gchar *value)
{
	while (date_list != NULL) {
		gchar *gstr = NULL;
		GDate *date_element = date_list->data;

		g_assert (date_element != NULL);

		gstr = g_strdup_printf("%04d-%02d-%02d",
		                       date_element->year,
		                       date_element->month,
		                       date_element->day);

		g_debug ("testing if date '%s' matches expected date '%s'", gstr, value);

		if (strcmp(gstr, value) == 0) {
			g_debug ("found date '%s'", gstr);
			free(gstr);
			return;
		}
		g_free(gstr);
		date_list = date_list->next;
	}
	g_debug ("date '%s' not found", value);
	g_assert_not_reached();
}

void
assert_String_in_list(GList *string_list, gchar *value)
{
	while (string_list != NULL) {
		gchar *element = string_list->data;
		g_assert (element != NULL);
		if (strcmp(element, value) == 0) {
			return;
		}
		string_list = string_list->next;
	}
	g_assert_not_reached();
}

void
assert_custom_field_in_list (GList *custom_list, gchar *custom_field_type, gchar *custom_field_name, gchar *field_value_exp) {

	while (custom_list != NULL) {
		Custom *custom = custom_list->data;
		g_assert (custom != NULL);
		if (strcmp(custom->app->str, custom_field_type) == 0 && strcmp(custom->name->str, custom_field_name) == 0) {
			g_assert_cmpstr(custom->value->str, ==, field_value_exp);
			return;
		}
		custom_list = custom_list->next;
	}
	g_assert_not_reached();
}

/* set value NULL in function call if element not available */
void
validate_iincidence(const I_incidence *iincidence, gchar *summary, gchar *location,
                    gchar *organizer_display_name, gchar *organizer_smtp_address,
                    gchar* start_date, gint stage)
{
	(void)stage;

	g_assert(iincidence != NULL);

	assert_equal(summary, iincidence->summary);
	assert_equal(location, iincidence->location);
	assert_equal(organizer_display_name, iincidence->organizer_display_name);
	assert_equal(organizer_smtp_address, iincidence->organizer_smtp_address);
	if (start_date != NULL) {
		g_assert(iincidence->start_date != NULL);
		if (iincidence->start_date->date != NULL)
			assert_equal_gdate(start_date, iincidence->start_date->date);
		else if (iincidence->start_date->date_time != NULL)
			assert_equal_timestamp(start_date, iincidence->start_date->date_time);
		else
			g_assert_not_reached();
	} else {
		g_assert(iincidence->start_date == NULL);
	}
	/* advanced_alarm (own function: assert_alarm_in_list())
	 * recurrence (own function: validate_recurrence())
	 * attendee-list (own function: assert_attendee_in_list())
	 */
}

void
validate_icommon(const I_common *icommon, gchar* exp_product_id, gchar* exp_uid,
                 gchar *exp_body, gchar *exp_categories, Sensitivity exp_sensitivity, gchar *exp_creation_date, gchar *exp_last_modification_date, gint stage)
{
	g_assert(icommon != NULL);
	if (IS_TEST_STAGE_INTERN_TO_KMAIL(stage)) /* own value is written when kolab xml is created */
		exp_product_id = KOLABCONV_PRODUCT_ID;
	else if (IS_TEST_STAGE_EVO_TO_INTERN(stage)) /* product id cannot be retrieved from evolution type */
		exp_product_id = NULL;
	assert_equal(exp_product_id, icommon->product_id);
	assert_equal(exp_uid, icommon->uid);
	assert_equal(exp_body, icommon->body);
	assert_equal(exp_categories, icommon->categories);
	g_debug ("testing if sensitivity '%d' matches expected sensitivity '%d'", icommon->sensitivity, exp_sensitivity);
	g_assert(icommon->sensitivity == exp_sensitivity);

	/*
	 * Evolution does not have a creation-date field for contacts, therefore we
	 * set a custom field 'X-KOLAB-CREATED'
	 * For new contacts created by Evolution libekolabconv sets
	 * this field to the value of the last-modification-date field.
	 *
	 * So if NULL is passed to this function as creation-date parameter,
	 * the original source file does not have a creation date set and we
	 * need to check if libekolabconv correctly sets it to last-modification-date.
	 *
	 * If both, expected creation-date and modification-date are NULL the original
	 * source file does not even have a modification date and libekolabconv should
	 * use the current system time for creation-date and last-modification-date.
	 */

	/* The dates should never be NULL */
	g_assert(icommon->creation_datetime != NULL);
	g_assert(icommon->creation_datetime->date_time != NULL);
	g_assert(icommon->last_modified_datetime != NULL);
	g_assert(icommon->last_modified_datetime->date_time != NULL);

	if(exp_creation_date != NULL && exp_last_modification_date != NULL) {
		assert_equal_timestamp(exp_creation_date, icommon->creation_datetime->date_time);
		assert_equal_timestamp(exp_last_modification_date, icommon->last_modified_datetime->date_time);
	}
	else if(exp_creation_date == NULL && exp_last_modification_date != NULL) {
		/* libekolabconv should have set last_modification_date as creation-date */
		assert_equal_timestamp(exp_last_modification_date, icommon->creation_datetime->date_time);
		assert_equal_timestamp(exp_last_modification_date, icommon->last_modified_datetime->date_time);
	}
	else if(exp_creation_date != NULL && exp_last_modification_date == NULL) {
		/* libekolabconv should have set creation_date as last_modification_date */
		assert_equal_timestamp(exp_creation_date, icommon->creation_datetime->date_time);
		assert_equal_timestamp(exp_creation_date, icommon->last_modified_datetime->date_time);
	} else {
		/* libekolabconv should have used current system time for both */
		assert_timestamp_not_older_than_10_seconds(icommon->creation_datetime->date_time);;
		assert_timestamp_not_older_than_10_seconds(icommon->last_modified_datetime->date_time);
	}
}


void
validate_recurrence(const Recurrence *recurrence, Recurrence_cycle cycle,
                    gint interval, gint range_number, gint *range_date, gint weekdays,
                    gint day_number, Month month)
{
	g_assert(recurrence != NULL);

	g_debug("recurrence (expected): recurrence_cycle: %i (%i), interval: %i (%i), range_number: %i (%i), "
	        "range_date %i-%i-%i (%i-%i-%i), weekdays: %i (%i), day_number: %i (%i), Month: %i (%i)",
	        recurrence->recurrence_cycle, cycle,
	        recurrence->interval, interval,
	        recurrence->range_number ? *recurrence->range_number : 0, range_number,
	        recurrence->range_date ? recurrence->range_date->year : 0, range_date ? *(range_date+2) : 0,
	        recurrence->range_date ? recurrence->range_date->month : 0, range_date ? *(range_date+1) : 0,
	        recurrence->range_date ? recurrence->range_date->day : 0, range_date ? *range_date : 0,
	        recurrence->weekdays, weekdays,
	        recurrence->day_number, day_number,
	        recurrence->month, month);

	g_assert(recurrence->recurrence_cycle == cycle);
	g_assert(recurrence->interval == interval);
	if (range_number <= 0)
		g_assert(recurrence->range_number == NULL);
	else {
		g_assert(recurrence->range_number != NULL);
		g_assert(*(recurrence->range_number) == range_number);
	}
	if (range_date == NULL)
		g_assert(recurrence->range_date == NULL);
	else {
		g_assert(recurrence->range_date != NULL);
		g_assert(recurrence->range_date->day == *range_date);
		g_assert(recurrence->range_date->month == *(range_date+1));
		g_assert(recurrence->range_date->year == *(range_date+2));
	}
	g_assert(recurrence->weekdays == weekdays);
	g_assert(recurrence->day_number == day_number);
	g_assert(recurrence->month == month);
}

void
assert_binary_attachment_equal(gchar *exp_data_file_name, gchar *name_exp, gchar *mime_type_exp, Kolab_conv_mail_part *value) {

	FILE *file;
	gchar *buffer;
	gulong fileLen;
	gint result;

	g_assert(value != NULL);

	g_assert_cmpstr(name_exp, ==, value->name);
	g_assert_cmpstr(mime_type_exp, ==, value->mime_type);

	g_debug("testing if attached binary value is equal to content of file '%s'", exp_data_file_name);

	/* Open file */
	file = fopen(exp_data_file_name, "rb");

	if(!file) {

		fprintf(stderr, "Unable to open file %s", exp_data_file_name);
		assert(FALSE);
	}

	/* Get file length */
	fseek(file, 0, SEEK_END);
	fileLen = ftell(file);
	g_assert_cmpint(fileLen, ==, value->length);
	fseek(file, 0, SEEK_SET);

	/* Allocate memory */
	buffer = g_new0(gchar, fileLen+1);
	if(!buffer) {

		fprintf(stderr, "Memory error!");
		fclose(file);
		return;
	}

	/* Read file contents into buffer */
	fread(buffer, fileLen, 1, file);
	fclose(file);

	result = memcmp(buffer, value->data, fileLen);
	g_free(buffer);

	g_assert(result == 0);
}

void
assert_binary_attachment_store_equal(gchar *exp_data_file_name, gchar *name_exp, gchar *mime_type_exp, I_common *icommon, gint idx) {
	Kolab_conv_mail_part *value = g_list_nth_data(icommon->kolab_attachment_store, idx);
	assert_binary_attachment_equal(exp_data_file_name, name_exp, mime_type_exp, value);
}

/*
 * helper function, turns integer into bitmask string
 */
gchar
*int_to_bitmask (gint i)
{
	gint digits = 8 * sizeof(gint);
	gint pos = 0;

	gchar *bitmask = g_new0(gchar, digits + digits/8);

	while (digits--) {
		if (pos && (digits+1) % 8 == 0)
			bitmask[pos++] = ' ';

		bitmask[pos++] = (i & 1<<digits) ? '1' : '0';
	}

	bitmask[pos] = '\0';

	return bitmask;
}

void
log_bitmask(gint stage)
{
	gchar *bmask = int_to_bitmask(stage);
	log_debug("Test stage: %s", bmask);
	g_free(bmask);
}

/**
 * Assert that the xml element with the given name is on the given index of the
 * list.
 */
void
validate_kolab_store_xml(GList *elements, gint index, gchar *name)
{
	GList *elem = g_list_nth(elements, index);
	gchar *xml_str = NULL;
	xmlDocPtr tree = NULL;

	g_assert(elem != NULL);

	xml_str = (gchar*)elem->data;
	/* gchar *xml_str = (gchar*)g_list_nth(elements, index)->data; */
	tree = xmlReadMemory (xml_str, strlen (xml_str), "test.xml", NULL, 0);
	g_assert(tree->type == XML_DOCUMENT_NODE);
	g_assert(tree->children != NULL);
	g_assert(tree->children->type == XML_ELEMENT_NODE);
	g_assert(strcmp((gchar*)tree->children->name, name) == 0);
	g_assert(tree->children->next == NULL);
	xmlFreeDoc(tree);
}

/*
 * strip carriage returns ('\r') from string (in place)
 *
 */
void
strip_cr(gchar *s)
{
	gchar *d = s;
	do {
		if (*s != '\r')
			*d++ = *s;
	} while (*s++);
}

/*
 * strip carriage returns ('\r') in copy of string
 *
 */
gchar *
strip_cr_cpy(const gchar *s)
{
	gchar *cpy = g_new0(gchar, strlen(s));
	gchar *d = cpy;

	do {
		if (*s != '\r')
			*d++ = *s;
	} while (*s++);

	return cpy;
}


void
validate_link_attachments(const I_common *icommon, ...)
{
	va_list ap;
	gchar* v1, *v2;
	GList *lal = icommon->link_attachments;
	va_start(ap, icommon);
	for (; lal != NULL; lal = lal->next) {
		v1 = (gchar*) lal->data;
		v2 = va_arg(ap, gchar*);
		g_assert_cmpstr (v1, ==, v2);
	}
	v2 = va_arg(ap, gchar*);
	g_assert(v2 == NULL);
	va_end(ap);
}

void
validate_inline_attachment_names(const I_common *icommon, ...)
{
	va_list ap;
	gchar* v1, *v2;
	GList *lal = icommon->inline_attachment_names;
	va_start(ap, icommon);
	for (; lal != NULL; lal = lal->next) {
		v1 = (gchar*) lal->data;
		v2 = va_arg(ap, gchar*);
		g_assert_cmpstr (v1, ==, v2);
	}
	v2 = va_arg(ap, gchar*);
	g_assert(v2 == NULL);
	va_end(ap);
}
