/*
 * Copyright © 2012 Intel Corporation
 * Copyright © 2012 Jason Ekstrand
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>

#include "wayland-private.h"
#include "wayland-server.h"
#include "test-runner.h"

static int
fd_dispatch(int fd, uint32_t mask, void *data)
{
	int *p = data;

	assert(mask == 0);
	++(*p);

	return 0;
}

TEST(event_loop_post_dispatch_check)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct wl_event_source *source;
	int dispatch_ran = 0;
	int p[2];

	assert(loop);
	assert(pipe(p) == 0);

	source = wl_event_loop_add_fd(loop, p[0], WL_EVENT_READABLE,
				      fd_dispatch, &dispatch_ran);
	assert(source);
	wl_event_source_check(source);

	wl_event_loop_dispatch(loop, 0);
	assert(dispatch_ran == 1);

	assert(close(p[0]) == 0);
	assert(close(p[1]) == 0);
	wl_event_source_remove(source);
	wl_event_loop_destroy(loop);
}

struct free_source_context {
	struct wl_event_source *source1, *source2;
	int p1[2], p2[2];
	int count;
};

static int
free_source_callback(int fd, uint32_t mask, void *data)
{
	struct free_source_context *context = data;

	context->count++;

	/* Remove other source */
	if (fd == context->p1[0]) {
		wl_event_source_remove(context->source2);
		context->source2 = NULL;
	} else if (fd == context->p2[0]) {
		wl_event_source_remove(context->source1);
		context->source1 = NULL;
	} else {
		assert(0);
	}

	return 1;
}

TEST(event_loop_free_source_with_data)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct free_source_context context;
	int data;

	/* This test is a little tricky to get right, since we don't
	 * have any guarantee from the event loop (ie epoll) on the
	 * order of which it reports events.  We want to have one
	 * source free the other, but we don't know which one is going
	 * to run first.  So we add two fd sources with a callback
	 * that frees the other source and check that only one of them
	 * run (and that we don't crash, of course).
	 */

	assert(loop);

	context.count = 0;
	assert(pipe(context.p1) == 0);
	assert(pipe(context.p2) == 0);
	context.source1 =
		wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE,
				     free_source_callback, &context);
	assert(context.source1);
	context.source2 =
		wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE,
				     free_source_callback, &context);
	assert(context.source2);

	data = 5;
	assert(write(context.p1[1], &data, sizeof data) == sizeof data);
	assert(write(context.p2[1], &data, sizeof data) == sizeof data);

	wl_event_loop_dispatch(loop, 0);

	assert(context.count == 1);

	if (context.source1)
		wl_event_source_remove(context.source1);
	if (context.source2)
		wl_event_source_remove(context.source2);
	wl_event_loop_destroy(loop);

	assert(close(context.p1[0]) == 0);
	assert(close(context.p1[1]) == 0);
	assert(close(context.p2[0]) == 0);
	assert(close(context.p2[1]) == 0);
}

static int
signal_callback(int signal_number, void *data)
{
	int *got_it = data;

	assert(signal_number == SIGUSR1);
	++(*got_it);

	return 1;
}

TEST(event_loop_signal)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct wl_event_source *source;
	int got_it = 0;

	source = wl_event_loop_add_signal(loop, SIGUSR1,
					  signal_callback, &got_it);
	assert(source);

	wl_event_loop_dispatch(loop, 0);
	assert(!got_it);
	kill(getpid(), SIGUSR1);
	wl_event_loop_dispatch(loop, 0);
	assert(got_it == 1);

	wl_event_source_remove(source);
	wl_event_loop_destroy(loop);
}

TEST(event_loop_multiple_same_signals)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct wl_event_source *s1, *s2;
	int calls_no = 0;
	int i;

	s1 = wl_event_loop_add_signal(loop, SIGUSR1,
				      signal_callback, &calls_no);
	assert(s1);

	s2 = wl_event_loop_add_signal(loop, SIGUSR1,
				      signal_callback, &calls_no);
	assert(s2);

	assert(wl_event_loop_dispatch(loop, 0) == 0);
	assert(!calls_no);

	/* Try it more times */
	for (i = 0; i < 5; ++i) {
		calls_no = 0;
		kill(getpid(), SIGUSR1);
		assert(wl_event_loop_dispatch(loop, 0) == 0);
		assert(calls_no == 2);
	}

	wl_event_source_remove(s1);

	/* Try it again  with one source */
	calls_no = 0;
	kill(getpid(), SIGUSR1);
	assert(wl_event_loop_dispatch(loop, 0) == 0);
	assert(calls_no == 1);

	wl_event_source_remove(s2);

	wl_event_loop_destroy(loop);
}

static int
timer_callback(void *data)
{
	int *got_it = data;

	++(*got_it);

	return 1;
}

TEST(event_loop_timer)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct wl_event_source *source1, *source2;
	int got_it = 0;

	source1 = wl_event_loop_add_timer(loop, timer_callback, &got_it);
	assert(source1);
	wl_event_source_timer_update(source1, 20);

	source2 = wl_event_loop_add_timer(loop, timer_callback, &got_it);
	assert(source2);
	wl_event_source_timer_update(source2, 100);

	/* Check that the timer marked for 20 msec from now fires within 30
	 * msec, and that the timer marked for 100 msec is expected to fire
	 * within an additional 90 msec. (Some extra wait time is provided to
	 * account for reasonable code execution / thread preemption delays.) */

	wl_event_loop_dispatch(loop, 0);
	assert(got_it == 0);
	wl_event_loop_dispatch(loop, 30);
	assert(got_it == 1);
	wl_event_loop_dispatch(loop, 0);
	assert(got_it == 1);
	wl_event_loop_dispatch(loop, 90);
	assert(got_it == 2);

	wl_event_source_remove(source1);
	wl_event_source_remove(source2);
	wl_event_loop_destroy(loop);
}

#define MSEC_TO_USEC(msec) ((msec) * 1000)

struct timer_update_context {
	struct wl_event_source *source1, *source2;
	int count;
};

static int
timer_update_callback_1(void *data)
{
	struct timer_update_context *context = data;

	context->count++;
	wl_event_source_timer_update(context->source2, 1000);
	return 1;
}

static int
timer_update_callback_2(void *data)
{
	struct timer_update_context *context = data;

	context->count++;
	wl_event_source_timer_update(context->source1, 1000);
	return 1;
}

TEST(event_loop_timer_updates)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct timer_update_context context;
	struct timeval start_time, end_time, interval;

	/* Create two timers that should expire at the same time (after 10ms).
	 * The first timer to receive its expiry callback updates the other timer
	 * with a much larger timeout (1s). This highlights a bug where
	 * wl_event_source_timer_dispatch would block for this larger timeout
	 * when reading from the timer fd, before calling the second timer's
	 * callback.
	 */

	context.source1 = wl_event_loop_add_timer(loop, timer_update_callback_1,
						  &context);
	assert(context.source1);
	assert(wl_event_source_timer_update(context.source1, 10) == 0);

	context.source2 = wl_event_loop_add_timer(loop, timer_update_callback_2,
						  &context);
	assert(context.source2);
	assert(wl_event_source_timer_update(context.source2, 10) == 0);

	context.count = 0;

	/* Since calling the functions between source2's update and
	 * wl_event_loop_dispatch() takes some time, it may happen
	 * that only one timer expires until we call epoll_wait.
	 * This naturally means that only one source is dispatched
	 * and the test fails. To fix that, sleep 15 ms before
	 * calling wl_event_loop_dispatch(). That should be enough
	 * for the second timer to expire.
	 *
	 * https://bugs.freedesktop.org/show_bug.cgi?id=80594
	 */
	usleep(MSEC_TO_USEC(15));

	gettimeofday(&start_time, NULL);
	wl_event_loop_dispatch(loop, 20);
	gettimeofday(&end_time, NULL);

	assert(context.count == 2);

	/* Dispatching the events should not have taken much more than 20ms,
	 * since this is the timeout passed to wl_event_loop_dispatch. If it
	 * blocked, then it will have taken over 1s.
	 * Of course, it could take over 1s anyway on a very slow or heavily
	 * loaded system, so this test isn't 100% perfect.
	 */

	timersub(&end_time, &start_time, &interval);
	assert(interval.tv_sec < 1);

	wl_event_source_remove(context.source1);
	wl_event_source_remove(context.source2);
	wl_event_loop_destroy(loop);
}

struct timer_order_data {
	struct wl_event_source *source;
	int *last_number;
	int number;
};

static int
timer_order_callback(void *data)
{
	struct timer_order_data *tod = data;

	/* Check that the timers have the correct sequence */
	assert(tod->number == *tod->last_number + 2);
	*tod->last_number = tod->number;
	return 0;
}

TEST(event_loop_timer_order)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct timer_order_data order[20];
	int i, j;
	int last = -1;

	/* Configure a set of timers so that only timers 1, 3, 5, ..., 19
	 * (in that order) will be dispatched when the event loop is run */

	for (i = 0; i < 20; i++) {
		order[i].number = i;
		order[i].last_number = &last;
		order[i].source =
			wl_event_loop_add_timer(loop, timer_order_callback,
						&order[i]);
		assert(order[i].source);
		assert(wl_event_source_timer_update(order[i].source, 10) == 0);
	}

	for (i = 0; i < 20; i++) {
		/* Permute the order in which timers are updated, so as to
		 * more exhaustively test the underlying priority queue code */
		j = ((i + 3) * 17) % 20;
		assert(wl_event_source_timer_update(order[j].source, j) == 0);
	}
	for (i = 0; i < 20; i += 2) {
		assert(wl_event_source_timer_update(order[i].source, 0) == 0);
	}

	/* Wait until all timers are due */
	usleep(MSEC_TO_USEC(21));
	wl_event_loop_dispatch(loop, 0);
	assert(last == 19);

	for (i = 0; i < 20; i++) {
		wl_event_source_remove(order[i].source);
	}
	wl_event_loop_destroy(loop);
}

struct timer_cancel_context {
	struct wl_event_source *timers[4];
	struct timer_cancel_context *back_refs[4];
	int order[4];
	int called, first;
};

static int
timer_cancel_callback(void *data) {
	struct timer_cancel_context **context_ref = data;
	struct timer_cancel_context *context = *context_ref;
	int i = (int)(context_ref - context->back_refs);

	context->called++;
	context->order[i] = context->called;

	if (context->called == 1) {
		context->first = i;
		/* Removing a timer always prevents its callback from
		 * being called ... */
		wl_event_source_remove(context->timers[(i + 1) % 4]);
		/* ... but disarming or rescheduling a timer does not,
		 * (in the case where the modified timers had already expired
		 * as of when `wl_event_loop_dispatch` was called.) */
		assert(wl_event_source_timer_update(context->timers[(i + 2) % 4],
						    0) == 0);
		assert(wl_event_source_timer_update(context->timers[(i + 3) % 4],
						    2000000000) == 0);
	}

	return 0;
}

TEST(event_loop_timer_cancellation)
{
	struct wl_event_loop *loop = wl_event_loop_create();
	struct timer_cancel_context context;
	int i;

	memset(&context, 0, sizeof(context));

	/* Test that when multiple timers are dispatched in a single call
	 * of `wl_event_loop_dispatch`, that having some timers run code
	 * to modify the other timers only actually prevents the other timers
	 * from running their callbacks when the those timers are removed, not
	 * when they are disarmed or rescheduled. */

	for (i = 0; i < 4; i++) {
		context.back_refs[i] = &context;
		context.timers[i] =
			wl_event_loop_add_timer(loop, timer_cancel_callback,
						&context.back_refs[i]);
		assert(context.timers[i]);

		assert(wl_event_source_timer_update(context.timers[i], 1) == 0);
	}

	usleep(MSEC_TO_USEC(2));
	assert(wl_event_loop_dispatch(loop, 0) == 0);

	/* Tracking which timer was first makes this test independent of the
	 * actual timer dispatch order, which is not guaranteed by the docs */
	assert(context.order[context.first] == 1);
	assert(context.order[(context.first + 1) % 4] == 0);
	assert(context.order[(context.first + 2) % 4] > 1);
	assert(context.order[(context.first + 3) % 4] > 1);

	wl_event_source_remove(context.timers[context.first]);
	wl_event_source_remove(context.timers[(context.first + 2) % 4]);
	wl_event_source_remove(context.timers[(context.first + 3) % 4]);

	wl_event_loop_destroy(loop);
}

struct event_loop_destroy_listener {
	struct wl_listener listener;
	int done;
};

static void
event_loop_destroy_notify(struct wl_listener *l, void *data)
{
	struct event_loop_destroy_listener *listener =
		wl_container_of(l, listener, listener);

	listener->done = 1;
}

TEST(event_loop_destroy)
{
	struct wl_event_loop *loop;
	struct wl_display * display;
	struct event_loop_destroy_listener a, b;

	loop = wl_event_loop_create();
	assert(loop);

	a.listener.notify = &event_loop_destroy_notify;
	a.done = 0;
	wl_event_loop_add_destroy_listener(loop, &a.listener);

	assert(wl_event_loop_get_destroy_listener(loop,
	       event_loop_destroy_notify) == &a.listener);

	b.listener.notify = &event_loop_destroy_notify;
	b.done = 0;
	wl_event_loop_add_destroy_listener(loop, &b.listener);

	wl_list_remove(&a.listener.link);
	wl_event_loop_destroy(loop);

	assert(!a.done);
	assert(b.done);

	/* Test to make sure it gets fired on display destruction */
	display = wl_display_create();
	assert(display);
	loop = wl_display_get_event_loop(display);
	assert(loop);

	a.done = 0;
	wl_event_loop_add_destroy_listener(loop, &a.listener);

	wl_display_destroy(display);

	assert(a.done);
}

