/*
 * 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 <stdint.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 },
	{ "noop", "", NULL },
};

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

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

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

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

};

enum {
	STOP_DISPLAY = 0,
	TEST_NOOP = 1
};

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_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_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_fd_leaks(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 void
handle_noop(struct wl_client *client, struct wl_resource *resource)
{
	(void)client;
	(void)resource;
}

static const struct test_compositor_interface tc_implementation = {
	handle_stop_display,
	handle_noop,
};

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;
	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;

	d->test_global = wl_global_create(d->wl_display,
					  &test_compositor_interface,
					  1, d, tc_bind);
	assert(d->test_global && "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_post_resume_events(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;
}

void
display_resume(struct display *d)
{
	display_post_resume_events(d);
	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_global_destroy(d->test_global);
	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;
}

void
noop_request(struct client *c)
{
	wl_proxy_marshal((struct wl_proxy *) c->tc, TEST_NOOP);
}
