/*
 * Copyright © 2012 Intel Corporation
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting documentation, and
 * that the name of the copyright holders not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  The copyright holders make no representations
 * about the suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "../src/wayland-private.h"
#include "test-runner.h"

TEST(list_init)
{
	struct wl_list list;

	wl_list_init(&list);
	assert(list.next == &list);
	assert(list.prev == &list);
	assert(wl_list_empty(&list));
}

struct element {
	int i;
	struct wl_list link;
};

TEST(list_insert)
{
	struct wl_list list;
	struct element e;

	wl_list_init(&list);
	wl_list_insert(&list, &e.link);
	assert(list.next == &e.link);
	assert(list.prev == &e.link);
	assert(e.link.next == &list);
	assert(e.link.prev == &list);
}

TEST(list_iterator)
{
	struct wl_list list;
	struct element e1, e2, e3, e4, *e;
	int reference[] = { 708090, 102030, 5588, 12 };
	unsigned int i;

	e1.i = 708090;
	e2.i = 102030;
	e3.i = 5588;
	e4.i = 12;

	wl_list_init(&list);
	wl_list_insert(list.prev, &e1.link);
	wl_list_insert(list.prev, &e2.link);
	wl_list_insert(list.prev, &e3.link);
	wl_list_insert(list.prev, &e4.link);

	i = 0;
	wl_list_for_each(e, &list, link) {
		assert(i < ARRAY_LENGTH(reference));
		assert(e->i == reference[i]);
		i++;
	}
	assert(i == ARRAY_LENGTH(reference));

	i = 0;
	wl_list_for_each_reverse(e, &list, link) {
		assert(i < ARRAY_LENGTH(reference));
		assert(e->i == reference[ARRAY_LENGTH(reference) - i - 1]);
		i++;
	}
	assert(i == ARRAY_LENGTH(reference));
}

static int
validate_list(struct wl_list *list, int *reference, int length)
{
	struct element *e;
	int i;

	i = 0;
	wl_list_for_each(e, list, link) {
		if (i >= length)
			return 0;
		if (e->i != reference[i])
			return 0;
		i++;
	}
		
	if (i != length)
		return 0;

	return 1;
}

TEST(list_remove)
{
	struct wl_list list;
	struct element e1, e2, e3;
	int reference1[] = { 17, 8888, 1000 }, reference2[] = { 17, 1000 };

	e1.i = 17;
	e2.i = 8888;
	e3.i = 1000;

	wl_list_init(&list);
	wl_list_insert(&list, &e1.link);
	wl_list_insert(list.prev, &e2.link);
	wl_list_insert(list.prev, &e3.link);
	assert(validate_list(&list, reference1, ARRAY_LENGTH(reference1)));

	wl_list_remove(&e2.link);
	assert(validate_list(&list, reference2, ARRAY_LENGTH(reference2)));
}

TEST(list_insert_list)
{
	struct wl_list list, other;
	struct element e1, e2, e3, e4, e5, e6;
	int reference1[] = { 17, 8888, 1000 };
	int reference2[] = { 76543, 1, -500 };
	int reference3[] = { 17, 76543, 1, -500, 8888, 1000 };

	e1.i = 17;
	e2.i = 8888;
	e3.i = 1000;

	wl_list_init(&list);
	wl_list_insert(&list, &e1.link);
	wl_list_insert(list.prev, &e2.link);
	wl_list_insert(list.prev, &e3.link);
	assert(validate_list(&list, reference1, ARRAY_LENGTH(reference1)));

	e4.i = 76543;
	e5.i = 1;
	e6.i = -500;

	wl_list_init(&other);
	wl_list_insert(&other, &e4.link);
	wl_list_insert(other.prev, &e5.link);
	wl_list_insert(other.prev, &e6.link);
	assert(validate_list(&other, reference2, ARRAY_LENGTH(reference2)));

	wl_list_insert_list(list.next, &other);
	assert(validate_list(&list, reference3, ARRAY_LENGTH(reference3)));
}
