/*
 * Copyright (c) 2014 Red Hat, Inc.
 *
 * 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 <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>

#define WL_HIDE_DEPRECATED

#include "test-runner.h"
#include "test-compositor.h"

/* --- Protocol --- */
struct test_compositor;

static const struct wl_message tc_requests[] = {
	/* this request serves as a barrier for synchronizing*/
	{ "stop_display", "u", NULL }
};

static const struct wl_message tc_events[] = {
	{ "display_resumed", "", NULL }
};

const struct wl_interface test_compositor_interface = {
	"test", 1,
	1, tc_requests,
	1, tc_events
};

struct test_compositor_interface {
	void (*stop_display)(struct wl_client *client,
			     struct wl_resource *resource,
			     uint32_t num);
};

struct test_compositor_listener {
	void (*display_resumed)(void *data, struct test_compositor *tc);

};

enum {
	STOP_DISPLAY = 0
};

enum {
	DISPLAY_RESUMED = 0
};

/* Since tests can run parallelly, we need unique socket names
 * for each test, otherwise the test can fail on wl_display_add_socket. */
static const char *
get_socket_name(void)
{
	struct timeval tv;
	static char retval[64];

	gettimeofday(&tv, NULL);
	snprintf(retval, sizeof retval, "wayland-test-%d-%ld%ld",
		 getpid(), tv.tv_sec, tv.tv_usec);

	return retval;
}

static void
handle_client_destroy(void *data)
{
	struct client_info *ci = data;
	struct display *d;
	siginfo_t status;

	d = ci->display;

	assert(waitid(P_PID, ci->pid, &status, WEXITED) != -1);

	switch (status.si_code) {
	case CLD_KILLED:
	case CLD_DUMPED:
		fprintf(stderr, "Client '%s' was killed by signal %d\n",
			ci->name, status.si_status);
		ci->exit_code = status.si_status;
		break;
	case CLD_EXITED:
		if (status.si_status != EXIT_SUCCESS)
			fprintf(stderr, "Client '%s' exited with code %d\n",
				ci->name, status.si_status);

		ci->exit_code = status.si_status;
		break;
	}

	++d->clients_terminated_no;
	if (d->clients_no == d->clients_terminated_no) {
		wl_display_terminate(d->wl_display);
	}

	/* the clients are not removed from the list, because
	 * at the end of the test we check the exit codes of all
	 * clients. In the case that the test would go through
	 * the clients list manually, zero out the wl_client as a sign
	 * that the client is not running anymore */
}

/**
 * Check client's state and terminate display when all clients exited
 */
static void
client_destroyed(struct wl_listener *listener, void *data)
{
	struct client_info *ci;
	struct display *d;
	struct wl_event_loop *loop;

	/* Wait for client in an idle handler to avoid blocking the actual
	 * client destruction (fd close etc. */
	ci = wl_container_of(listener, ci, destroy_listener);
	d = ci->display;
	loop = wl_display_get_event_loop(d->wl_display);
	wl_event_loop_add_idle(loop, handle_client_destroy, ci);

	ci->wl_client = NULL;
}

static void
run_client(void (*client_main)(void *data), void *data,
	   int wayland_sock, int client_pipe)
{
	char s[8];
	int cur_alloc, cur_fds;
	int can_continue = 0;

	/* Wait until display signals that client can continue */
	assert(read(client_pipe, &can_continue, sizeof(int)) == sizeof(int));

	if (can_continue == 0)
		abort(); /* error in parent */

	/* for wl_display_connect() */
	snprintf(s, sizeof s, "%d", wayland_sock);
	setenv("WAYLAND_SOCKET", s, 0);

	cur_alloc = get_current_alloc_num();
	cur_fds = count_open_fds();

	client_main(data);

	/* Clients using wl_display_connect() will end up closing the socket
	 * passed in through the WAYLAND_SOCKET environment variable. When
	 * doing this, it clears the environment variable, so if it's been
	 * unset, then we assume the client consumed the file descriptor and
	 * do not count it towards leak checking. */
	if (!getenv("WAYLAND_SOCKET"))
		cur_fds--;

	check_leaks(cur_alloc, cur_fds);
}

static struct client_info *
display_create_client(struct display *d,
		      void (*client_main)(void *data),
		      void *data,
		      const char *name)
{
	int pipe_cli[2];
	int sock_wayl[2];
	pid_t pid;
	int can_continue = 0;
	struct client_info *cl;

	assert(pipe(pipe_cli) == 0 && "Failed creating pipe");
	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_wayl) == 0
	       && "Failed creating socket pair");

	pid = fork();
	assert(pid != -1 && "Fork failed");

	if (pid == 0) {
		close(sock_wayl[1]);
		close(pipe_cli[1]);

		run_client(client_main, data, sock_wayl[0], pipe_cli[0]);

		close(sock_wayl[0]);
		close(pipe_cli[0]);

		exit(0);
	}

	close(sock_wayl[0]);
	close(pipe_cli[0]);

	cl = calloc(1, sizeof(struct client_info));
	assert(cl && "Out of memory");

	wl_list_insert(&d->clients, &cl->link);

	cl->display = d;
	cl->name = name;
	cl->pid = pid;
	cl->pipe = pipe_cli[1];
	cl->destroy_listener.notify = &client_destroyed;

	cl->wl_client = wl_client_create(d->wl_display, sock_wayl[1]);
	if (!cl->wl_client) {
		int ret;

		/* abort the client */
		ret = write(cl->pipe, &can_continue, sizeof(int));
		assert(ret == sizeof(int) && "aborting the client failed");
		assert(0 && "Couldn't create wayland client");
	}

	wl_client_add_destroy_listener(cl->wl_client,
				       &cl->destroy_listener);

	++d->clients_no;

	return cl;
}

struct client_info *
client_create_with_name(struct display *d,
			void (*client_main)(void *data), void *data,
			const char *name)
{
	int can_continue = 1;
	struct client_info *cl = display_create_client(d,
						       client_main, data,
						       name);

	/* let the show begin! */
	assert(write(cl->pipe, &can_continue, sizeof(int)) == sizeof(int));

	return cl;
}

/* wfr = waiting for resume */
struct wfr {
	struct wl_resource *resource;
	struct wl_list link;
};

static void
handle_stop_display(struct wl_client *client,
		    struct wl_resource *resource, uint32_t num)
{
	struct display *d = wl_resource_get_user_data(resource);
	struct wfr *wfr;

	assert(d->wfr_num < num
	       && "test error: Too many clients sent stop_display request");

	++d->wfr_num;

	wfr = malloc(sizeof *wfr);
	if (!wfr) {
		wl_client_post_no_memory(client);
		assert(0 && "Out of memory");
	}

	wfr->resource = resource;
	wl_list_insert(&d->waiting_for_resume, &wfr->link);

	if (d->wfr_num == num)
		wl_display_terminate(d->wl_display);
}

static const struct test_compositor_interface tc_implementation = {
	handle_stop_display
};

static void
tc_bind(struct wl_client *client, void *data,
	uint32_t ver, uint32_t id)
{
	struct wl_resource *res;

	res = wl_resource_create(client, &test_compositor_interface, ver, id);
	if (!res) {
		wl_client_post_no_memory(client);
		assert(0 && "Out of memory");
	}

	wl_resource_set_implementation(res, &tc_implementation, data, NULL);
}

struct display *
display_create(void)
{
	struct display *d = NULL;
	struct wl_global *g;
	const char *socket_name;
	int stat = 0;

	d = calloc(1, sizeof *d);
	assert(d && "Out of memory");

	d->wl_display = wl_display_create();
	assert(d->wl_display && "Creating display failed");

	/* hope the path won't be longer than 108 ... */
	socket_name = get_socket_name();
	stat = wl_display_add_socket(d->wl_display, socket_name);
	assert(stat == 0 && "Failed adding socket");

	wl_list_init(&d->clients);
	d->clients_no = d->clients_terminated_no = 0;

	wl_list_init(&d->waiting_for_resume);
	d->wfr_num = 0;

	g = wl_global_create(d->wl_display, &test_compositor_interface,
			     1, d, tc_bind);
	assert(g && "Creating test global failed");

	return d;
}

void
display_run(struct display *d)
{
	assert(d->wfr_num == 0
	       && "test error: Have waiting clients. Use display_resume.");
	wl_display_run(d->wl_display);
}

void
display_resume(struct display *d)
{
	struct wfr *wfr, *next;

	assert(d->wfr_num > 0 && "test error: No clients waiting.");

	wl_list_for_each_safe(wfr, next, &d->waiting_for_resume, link) {
		wl_resource_post_event(wfr->resource, DISPLAY_RESUMED);
		wl_list_remove(&wfr->link);
		free(wfr);
	}

	assert(wl_list_empty(&d->waiting_for_resume));
	d->wfr_num = 0;

	wl_display_run(d->wl_display);
}

void
display_destroy(struct display *d)
{
	struct client_info *cl, *next;
	int failed = 0;

	assert(d->wfr_num == 0
	       && "test error: Didn't you forget to call display_resume?");

	wl_list_for_each_safe(cl, next, &d->clients, link) {
		assert(cl->wl_client == NULL);

		if (cl->exit_code != 0) {
			++failed;
			fprintf(stderr, "Client '%s' failed\n", cl->name);
		}

		close(cl->pipe);
		free(cl);
	}

	wl_display_destroy(d->wl_display);
	free(d);

	if (failed) {
		fprintf(stderr, "%d child(ren) failed\n", failed);
		abort();
	}
}

/*
 * --- Client helper functions ---
 */
static void
handle_display_resumed(void *data, struct test_compositor *tc)
{
	struct client *c = data;

	c->display_stopped = 0;
}

static const struct test_compositor_listener tc_listener = {
	handle_display_resumed
};

static void
registry_handle_globals(void *data, struct wl_registry *registry,
			uint32_t id, const char *intf, uint32_t ver)
{
	struct client *c = data;

	if (strcmp(intf, "test") != 0)
		return;

	c->tc = wl_registry_bind(registry, id, &test_compositor_interface, ver);
	assert(c->tc && "Failed binding to registry");

	wl_proxy_add_listener((struct wl_proxy *) c->tc,
			      (void *) &tc_listener, c);
}

static const struct wl_registry_listener registry_listener =
{
	registry_handle_globals,
	NULL
};

struct client *client_connect()
{
	struct wl_registry *reg;
	struct client *c = calloc(1, sizeof *c);
	assert(c && "Out of memory");

	c->wl_display = wl_display_connect(NULL);
	assert(c->wl_display && "Failed connecting to display");

	/* create test_compositor proxy. Do it with temporary
	 * registry so that client can define it's own listener later */
	reg = wl_display_get_registry(c->wl_display);
	assert(reg);
	wl_registry_add_listener(reg, &registry_listener, c);
	wl_display_roundtrip(c->wl_display);
	assert(c->tc);

	wl_registry_destroy(reg);

	return c;
}

static void
check_error(struct wl_display *display)
{
	uint32_t ec, id;
	const struct wl_interface *intf;
	int err;

	err = wl_display_get_error(display);
	/* write out message about protocol error */
	if (err == EPROTO) {
		ec = wl_display_get_protocol_error(display, &intf, &id);
		fprintf(stderr, "Client: Got protocol error %u on interface %s"
				" (object %u)\n", ec, intf->name, id);
	}

	if (err) {
		fprintf(stderr, "Client error: %s\n", strerror(err));
		abort();
	}
}

void
client_disconnect(struct client *c)
{
	/* check for errors */
	check_error(c->wl_display);

	wl_proxy_destroy((struct wl_proxy *) c->tc);
	wl_display_disconnect(c->wl_display);
	free(c);
}

/* num is number of clients that requests to stop display.
 * Display is stopped after it receives num STOP_DISPLAY requests */
int
stop_display(struct client *c, int num)
{
	int n = 0;

	c->display_stopped = 1;
	wl_proxy_marshal((struct wl_proxy *) c->tc, STOP_DISPLAY, num);

	while (c->display_stopped && n >= 0) {
		n = wl_display_dispatch(c->wl_display);
	}

	return n;
}
