/*
 * Copyright © 2012 Intel Corporation
 * Copyright © 2013 DENSO CORPORATION
 * Copyright © 2015 Collabora, Ltd.
 *
 * 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 "config.h"

#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <assert.h>
#include <limits.h>

#include "compositor.h"
#include "compositor/weston.h"
#include "weston-test-server-protocol.h"
#include "ivi-test.h"
#include "ivi-shell/ivi-layout-export.h"
#include "shared/helpers.h"

struct test_context;

struct runner_test {
	const char *name;
	void (*run)(struct test_context *);
} __attribute__ ((aligned (32)));

#define RUNNER_TEST(name)					\
	static void runner_func_##name(struct test_context *);	\
								\
	const struct runner_test runner_test_##name		\
		__attribute__ ((section ("test_section"))) =	\
	{							\
		#name, runner_func_##name			\
	};							\
								\
	static void runner_func_##name(struct test_context *ctx)

extern const struct runner_test __start_test_section;
extern const struct runner_test __stop_test_section;

static const struct runner_test *
find_runner_test(const char *name)
{
	const struct runner_test *t;

	for (t = &__start_test_section; t < &__stop_test_section; t++) {
		if (strcmp(t->name, name) == 0)
			return t;
	}

	return NULL;
}

struct test_launcher {
	struct weston_compositor *compositor;
	char exe[2048];
	struct weston_process process;
	const struct ivi_layout_interface *layout_interface;
};

struct test_context {
	const struct ivi_layout_interface *layout_interface;
	struct wl_resource *runner_resource;
	uint32_t user_flags;

	struct wl_listener surface_property_changed;
	struct wl_listener surface_created;
	struct wl_listener surface_removed;
	struct wl_listener surface_configured;
};

static struct test_context static_context;

static void
destroy_runner(struct wl_resource *resource)
{
	assert(static_context.runner_resource == NULL ||
	       static_context.runner_resource == resource);

	static_context.layout_interface = NULL;
	static_context.runner_resource = NULL;
}

static void
runner_destroy_handler(struct wl_client *client, struct wl_resource *resource)
{
	wl_resource_destroy(resource);
}

static void
runner_run_handler(struct wl_client *client, struct wl_resource *resource,
		   const char *test_name)
{
	struct test_launcher *launcher;
	const struct runner_test *t;

	assert(static_context.runner_resource == NULL ||
	       static_context.runner_resource == resource);

	launcher = wl_resource_get_user_data(resource);
	static_context.layout_interface = launcher->layout_interface;
	static_context.runner_resource = resource;

	t = find_runner_test(test_name);
	if (!t) {
		weston_log("Error: runner test \"%s\" not found.\n",
			   test_name);
		wl_resource_post_error(resource,
				       WESTON_TEST_RUNNER_ERROR_UNKNOWN_TEST,
				       "weston_test_runner: unknown: '%s'",
				       test_name);
		return;
	}

	weston_log("weston_test_runner.run(\"%s\")\n", test_name);

	t->run(&static_context);

	weston_test_runner_send_finished(resource);
}

static const struct weston_test_runner_interface runner_implementation = {
	runner_destroy_handler,
	runner_run_handler
};

static void
bind_runner(struct wl_client *client, void *data,
	    uint32_t version, uint32_t id)
{
	struct test_launcher *launcher = data;
	struct wl_resource *resource;

	resource = wl_resource_create(client, &weston_test_runner_interface,
				      1, id);
	if (!resource) {
		wl_client_post_no_memory(client);
		return;
	}

	wl_resource_set_implementation(resource, &runner_implementation,
				       launcher, destroy_runner);

	if (static_context.runner_resource != NULL) {
		weston_log("test FATAL: "
			   "attempting to run several tests in parallel.\n");
		wl_resource_post_error(resource,
				       WESTON_TEST_RUNNER_ERROR_TEST_FAILED,
				       "attempt to run parallel tests");
	}
}

static void
test_client_sigchld(struct weston_process *process, int status)
{
	struct test_launcher *launcher =
		container_of(process, struct test_launcher, process);
	struct weston_compositor *c = launcher->compositor;

	/* Chain up from weston-test-runner's exit code so that automake
	 * knows the exit status and can report e.g. skipped tests. */
	if (WIFEXITED(status))
		weston_compositor_exit_with_code(c, WEXITSTATUS(status));
	else
		weston_compositor_exit_with_code(c, EXIT_FAILURE);
}

static void
idle_launch_client(void *data)
{
	struct test_launcher *launcher = data;
	pid_t pid;
	sigset_t allsigs;

	pid = fork();
	if (pid == -1) {
		weston_log("fatal: failed to fork '%s': %m\n", launcher->exe);
		weston_compositor_exit_with_code(launcher->compositor,
						 EXIT_FAILURE);
		return;
	}

	if (pid == 0) {
		sigfillset(&allsigs);
		sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
		execl(launcher->exe, launcher->exe, NULL);
		weston_log("compositor: executing '%s' failed: %m\n",
			   launcher->exe);
		_exit(EXIT_FAILURE);
	}

	launcher->process.pid = pid;
	launcher->process.cleanup = test_client_sigchld;
	weston_watch_process(&launcher->process);
}

WL_EXPORT int
wet_module_init(struct weston_compositor *compositor,
		       int *argc, char *argv[])
{
	struct wl_event_loop *loop;
	struct test_launcher *launcher;
	const struct ivi_layout_interface *iface;

	iface = ivi_layout_get_api(compositor);

	if (!iface) {
		weston_log("fatal: cannot use ivi_layout_interface.\n");
		return -1;
	}

	launcher = zalloc(sizeof *launcher);
	if (!launcher)
		return -1;

	if (weston_module_path_from_env("ivi-layout-test-client.ivi",
					launcher->exe,
					sizeof launcher->exe) == 0) {
		weston_log("test setup failure: WESTON_MODULE_MAP not set\n");
		return -1;
	}

	launcher->compositor = compositor;
	launcher->layout_interface = iface;

	if (wl_global_create(compositor->wl_display,
			     &weston_test_runner_interface, 1,
			     launcher, bind_runner) == NULL)
		return -1;

	loop = wl_display_get_event_loop(compositor->wl_display);
	wl_event_loop_add_idle(loop, idle_launch_client, launcher);

	return 0;
}

static void
runner_assert_fail(const char *cond, const char *file, int line,
		   const char *func, struct test_context *ctx)
{
	weston_log("Assert failure in %s:%d, %s: '%s'\n",
		   file, line, func, cond);

	assert(ctx->runner_resource);
	wl_resource_post_error(ctx->runner_resource,
			       WESTON_TEST_RUNNER_ERROR_TEST_FAILED,
			       "Assert failure in %s:%d, %s: '%s'\n",
			       file, line, func, cond);
}

#define runner_assert(cond) ({					\
	bool b_ = (cond);					\
	if (!b_)						\
		runner_assert_fail(#cond, __FILE__, __LINE__,	\
				   __func__, ctx);		\
	b_;							\
})

#define runner_assert_or_return(cond) do {			\
	bool b_ = (cond);					\
	if (!b_) {						\
		runner_assert_fail(#cond, __FILE__, __LINE__,	\
				   __func__, ctx);		\
		return;						\
	}							\
} while (0)


/*************************** tests **********************************/

/*
 * This is a controller module: a plugin to ivi-shell.so, i.e. a sub-plugin.
 * This module is specially written to execute tests that target the
 * ivi_layout API.
 *
 * This module is listed in TESTS in Makefile.am. weston-tests-env handles
 * this module specially by loading it in ivi-shell.
 *
 * Once Weston init completes, this module launches one test program:
 * ivi-layout-test-client.ivi (ivi-layout-test-client.c).
 * That program uses the weston-test-runner
 * framework to fork and exec each TEST() in ivi-layout-test-client.c with a fresh
 * connection to the single compositor instance.
 *
 * Each TEST() in ivi-layout-test-client.c will bind to weston_test_runner global
 * interface. A TEST() will set up the client state, and issue
 * weston_test_runner.run request to execute the compositor-side of the test.
 *
 * The compositor-side parts of the tests are in this file. They are specified
 * by RUNNER_TEST() macro, where the name argument matches the name string
 * passed to weston_test_runner.run.
 *
 * A RUNNER_TEST() function simply returns when it succeeds. If it fails,
 * a fatal protocol error is sent to the client from runner_assert() or
 * runner_assert_or_return(). This module catches the test program exit
 * code and passes it out of Weston to the test harness.
 *
 * A single TEST() in ivi-layout-test-client.c may use multiple RUNNER_TEST()s to
 * achieve multiple test points over a client action sequence.
 */

RUNNER_TEST(surface_create_p1)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf[2];
	uint32_t ivi_id;

	ivisurf[0] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf[0]);

	ivisurf[1] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(1));
	runner_assert(ivisurf[1]);

	ivi_id = lyt->get_id_of_surface(ivisurf[0]);
	runner_assert(ivi_id == IVI_TEST_SURFACE_ID(0));

	ivi_id = lyt->get_id_of_surface(ivisurf[1]);
	runner_assert(ivi_id == IVI_TEST_SURFACE_ID(1));
}

RUNNER_TEST(surface_create_p2)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	/* the ivi_surface was destroyed by the client */
	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf == NULL);
}

RUNNER_TEST(surface_visibility)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	int32_t ret;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf);

	ret = lyt->surface_set_visibility(ivisurf, true);
	runner_assert(ret == IVI_SUCCEEDED);

	lyt->commit_changes();

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert(prop->visibility == true);
}

RUNNER_TEST(surface_opacity)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	int32_t ret;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert(prop->opacity == wl_fixed_from_double(1.0));

	ret = lyt->surface_set_opacity(ivisurf, wl_fixed_from_double(0.5));
	runner_assert(ret == IVI_SUCCEEDED);

	runner_assert(prop->opacity == wl_fixed_from_double(1.0));

	lyt->commit_changes();

	runner_assert(prop->opacity == wl_fixed_from_double(0.5));
}

RUNNER_TEST(surface_dimension)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_width == 1);
	runner_assert(prop->dest_height == 1);

	runner_assert(IVI_SUCCEEDED ==
		      lyt->surface_set_destination_rectangle(ivisurf, prop->dest_x,
		      prop->dest_y, 200, 300));

	runner_assert(prop->dest_width == 1);
	runner_assert(prop->dest_height == 1);

	lyt->commit_changes();

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_width == 200);
	runner_assert(prop->dest_height == 300);
}

RUNNER_TEST(surface_position)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_x == 0);
	runner_assert(prop->dest_y == 0);

	runner_assert(lyt->surface_set_destination_rectangle(
		      ivisurf, 20, 30,
		      prop->dest_width, prop->dest_height) == IVI_SUCCEEDED);

	runner_assert(prop->dest_x == 0);
	runner_assert(prop->dest_y == 0);

	lyt->commit_changes();

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_x == 20);
	runner_assert(prop->dest_y == 30);
}

RUNNER_TEST(surface_destination_rectangle)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_width == 1);
	runner_assert(prop->dest_height == 1);
	runner_assert(prop->dest_x == 0);
	runner_assert(prop->dest_y == 0);

	runner_assert(lyt->surface_set_destination_rectangle(
		      ivisurf, 20, 30, 200, 300) == IVI_SUCCEEDED);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_width == 1);
	runner_assert(prop->dest_height == 1);
	runner_assert(prop->dest_x == 0);
	runner_assert(prop->dest_y == 0);

	lyt->commit_changes();

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->dest_width == 200);
	runner_assert(prop->dest_height == 300);
	runner_assert(prop->dest_x == 20);
	runner_assert(prop->dest_y == 30);
}

RUNNER_TEST(surface_source_rectangle)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->source_width == 0);
	runner_assert(prop->source_height == 0);
	runner_assert(prop->source_x == 0);
	runner_assert(prop->source_y == 0);

	runner_assert(lyt->surface_set_source_rectangle(
		      ivisurf, 20, 30, 200, 300) == IVI_SUCCEEDED);

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->source_width == 0);
	runner_assert(prop->source_height == 0);
	runner_assert(prop->source_x == 0);
	runner_assert(prop->source_y == 0);

	lyt->commit_changes();

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert_or_return(prop);
	runner_assert(prop->source_width == 200);
	runner_assert(prop->source_height == 300);
	runner_assert(prop->source_x == 20);
	runner_assert(prop->source_y == 30);
}

RUNNER_TEST(surface_bad_opacity)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	const struct ivi_layout_surface_properties *prop;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	runner_assert(lyt->surface_set_opacity(
		      NULL, wl_fixed_from_double(0.3)) == IVI_FAILED);

	runner_assert(lyt->surface_set_opacity(
		      ivisurf, wl_fixed_from_double(0.3)) == IVI_SUCCEEDED);

	runner_assert(lyt->surface_set_opacity(
		      ivisurf, wl_fixed_from_double(-1)) == IVI_FAILED);

	lyt->commit_changes();

	prop = lyt->get_properties_of_surface(ivisurf);
	runner_assert(prop->opacity == wl_fixed_from_double(0.3));

	runner_assert(lyt->surface_set_opacity(
		      ivisurf, wl_fixed_from_double(1.1)) == IVI_FAILED);

	lyt->commit_changes();

	runner_assert(prop->opacity == wl_fixed_from_double(0.3));

	runner_assert(lyt->surface_set_opacity(
		      NULL, wl_fixed_from_double(0.5)) == IVI_FAILED);

	lyt->commit_changes();
}

RUNNER_TEST(surface_on_many_layer)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;
	struct ivi_layout_layer *ivilayers[IVI_TEST_LAYER_COUNT] = {};
	struct ivi_layout_layer **array;
	int32_t length = 0;
	uint32_t i;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	for (i = 0; i < IVI_TEST_LAYER_COUNT; i++) {
		ivilayers[i] = lyt->layer_create_with_dimension(
				IVI_TEST_LAYER_ID(i), 200, 300);
		runner_assert(lyt->layer_add_surface(
				ivilayers[i], ivisurf) == IVI_SUCCEEDED);
	}

	lyt->commit_changes();

	runner_assert(lyt->get_layers_under_surface(
		      ivisurf, &length, &array) == IVI_SUCCEEDED);
	runner_assert(IVI_TEST_LAYER_COUNT == length);
	for (i = 0; i < IVI_TEST_LAYER_COUNT; i++)
		runner_assert(array[i] == ivilayers[i]);

	if (length > 0)
		free(array);

	for (i = 0; i < IVI_TEST_LAYER_COUNT; i++)
		lyt->layer_remove_surface(ivilayers[i], ivisurf);

	array = NULL;

	lyt->commit_changes();

	runner_assert(lyt->get_layers_under_surface(
		      ivisurf, &length, &array) == IVI_SUCCEEDED);
	runner_assert(length == 0 && array == NULL);

	for (i = 0; i < IVI_TEST_LAYER_COUNT; i++)
		lyt->layer_destroy(ivilayers[i]);
}

RUNNER_TEST(ivi_layout_commit_changes)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;

	lyt->commit_changes();
}

RUNNER_TEST(commit_changes_after_visibility_set_surface_destroy)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);
	runner_assert(lyt->surface_set_visibility(
		      ivisurf, true) == IVI_SUCCEEDED);
}

RUNNER_TEST(commit_changes_after_opacity_set_surface_destroy)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);
	runner_assert(lyt->surface_set_opacity(
		      ivisurf, wl_fixed_from_double(0.5)) == IVI_SUCCEEDED);
}

RUNNER_TEST(commit_changes_after_source_rectangle_set_surface_destroy)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);
	runner_assert(lyt->surface_set_source_rectangle(
		      ivisurf, 20, 30, 200, 300) == IVI_SUCCEEDED);
}

RUNNER_TEST(commit_changes_after_destination_rectangle_set_surface_destroy)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);
	runner_assert(lyt->surface_set_destination_rectangle(
		      ivisurf, 20, 30, 200, 300) == IVI_SUCCEEDED);
}

RUNNER_TEST(get_surface_after_destroy_surface)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf == NULL);
}

RUNNER_TEST(layer_render_order)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;
	struct ivi_layout_surface *ivisurfs[IVI_TEST_SURFACE_COUNT] = {};
	struct ivi_layout_surface **array;
	int32_t length = 0;
	uint32_t i;

	ivilayer = lyt->layer_create_with_dimension(IVI_TEST_LAYER_ID(0), 200, 300);

	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		ivisurfs[i] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(i));

	runner_assert(lyt->layer_set_render_order(
		      ivilayer, ivisurfs, IVI_TEST_SURFACE_COUNT) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, &array) == IVI_SUCCEEDED);
	runner_assert(IVI_TEST_SURFACE_COUNT == length);
	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		runner_assert(array[i] == ivisurfs[i]);

	if (length > 0)
		free(array);

	runner_assert(lyt->layer_set_render_order(
		      ivilayer, NULL, 0) == IVI_SUCCEEDED);

	array = NULL;

	lyt->commit_changes();

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, &array) == IVI_SUCCEEDED);
	runner_assert(length == 0 && array == NULL);

	lyt->layer_destroy(ivilayer);
}

RUNNER_TEST(test_layer_render_order_destroy_one_surface_p1)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;
	struct ivi_layout_surface *ivisurfs[IVI_TEST_SURFACE_COUNT] = {};
	struct ivi_layout_surface **array;
	int32_t length = 0;
	int32_t i;

	ivilayer = lyt->layer_create_with_dimension(IVI_TEST_LAYER_ID(0), 200, 300);

	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		ivisurfs[i] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(i));

	runner_assert(lyt->layer_set_render_order(
		      ivilayer, ivisurfs, IVI_TEST_SURFACE_COUNT) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, &array) == IVI_SUCCEEDED);
	runner_assert(IVI_TEST_SURFACE_COUNT == length);
	for (i = 0; i < length; i++)
		runner_assert(array[i] == ivisurfs[i]);

	if (length > 0)
		free(array);
}

RUNNER_TEST(test_layer_render_order_destroy_one_surface_p2)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;
	struct ivi_layout_surface *ivisurfs[2] = {};
	struct ivi_layout_surface **array;
	int32_t length = 0;
	int32_t i;

	ivilayer = lyt->get_layer_from_id(IVI_TEST_LAYER_ID(0));
	ivisurfs[0] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	ivisurfs[1] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(2));

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, &array) == IVI_SUCCEEDED);
	runner_assert(2 == length);
	for (i = 0; i < length; i++)
		runner_assert(array[i] == ivisurfs[i]);

	if (length > 0)
		free(array);

	lyt->layer_destroy(ivilayer);
}

RUNNER_TEST(layer_bad_render_order)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;
	struct ivi_layout_surface *ivisurfs[IVI_TEST_SURFACE_COUNT] = {};
	struct ivi_layout_surface **array = NULL;
	int32_t length = 0;
	uint32_t i;

	ivilayer = lyt->layer_create_with_dimension(IVI_TEST_LAYER_ID(0), 200, 300);

	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		ivisurfs[i] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(i));

	runner_assert(lyt->layer_set_render_order(
		      NULL, ivisurfs, IVI_TEST_SURFACE_COUNT) == IVI_FAILED);

	lyt->commit_changes();

	runner_assert(lyt->get_surfaces_on_layer(
		      NULL, &length, &array) == IVI_FAILED);
	runner_assert(length == 0 && array == NULL);

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, NULL, &array) == IVI_FAILED);
	runner_assert(array == NULL);

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, NULL) == IVI_FAILED);
	runner_assert(length == 0);

	lyt->layer_destroy(ivilayer);
}

RUNNER_TEST(layer_add_surfaces)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;
	struct ivi_layout_surface *ivisurfs[IVI_TEST_SURFACE_COUNT] = {};
	struct ivi_layout_surface **array;
	int32_t length = 0;
	uint32_t i;

	ivilayer = lyt->layer_create_with_dimension(IVI_TEST_LAYER_ID(0), 200, 300);

	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++) {
		ivisurfs[i] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(i));
		runner_assert(lyt->layer_add_surface(
				      ivilayer, ivisurfs[i]) == IVI_SUCCEEDED);
	}

	lyt->commit_changes();

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, &array) == IVI_SUCCEEDED);
	runner_assert(IVI_TEST_SURFACE_COUNT == length);
	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		runner_assert(array[i] == ivisurfs[i]);

	if (length > 0)
		free(array);

	runner_assert(lyt->layer_set_render_order(
		      ivilayer, NULL, 0) == IVI_SUCCEEDED);

	for (i = IVI_TEST_SURFACE_COUNT; i-- > 0;)
		runner_assert(lyt->layer_add_surface(
				      ivilayer, ivisurfs[i]) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(lyt->get_surfaces_on_layer(
		      ivilayer, &length, &array) == IVI_SUCCEEDED);
	runner_assert(IVI_TEST_SURFACE_COUNT == length);
	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		runner_assert(array[i] == ivisurfs[IVI_TEST_SURFACE_COUNT - (i + 1)]);

	if (length > 0)
		free(array);

	lyt->layer_destroy(ivilayer);
}

RUNNER_TEST(commit_changes_after_render_order_set_surface_destroy)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;
	struct ivi_layout_surface *ivisurfs[IVI_TEST_SURFACE_COUNT] = {};
	int i;

	ivilayer = lyt->layer_create_with_dimension(IVI_TEST_LAYER_ID(0), 200, 300);

	for (i = 0; i < IVI_TEST_SURFACE_COUNT; i++)
		ivisurfs[i] = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(i));

	runner_assert(lyt->layer_set_render_order(
		      ivilayer, ivisurfs, IVI_TEST_SURFACE_COUNT) == IVI_SUCCEEDED);
}

RUNNER_TEST(cleanup_layer)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_layer *ivilayer;

	ivilayer = lyt->get_layer_from_id(IVI_TEST_LAYER_ID(0));
	lyt->layer_destroy(ivilayer);
}

static void
test_surface_properties_changed_notification_callback(struct wl_listener *listener, void *data)

{
	struct test_context *ctx =
			container_of(listener, struct test_context,
					surface_property_changed);
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf = data;

	runner_assert_or_return(lyt->get_id_of_surface(ivisurf) == IVI_TEST_SURFACE_ID(0));

	ctx->user_flags = 1;
}

RUNNER_TEST(surface_properties_changed_notification)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	const uint32_t id_surface = IVI_TEST_SURFACE_ID(0);
	struct ivi_layout_surface *ivisurf;

	ctx->user_flags = 0;

	ivisurf = lyt->get_surface_from_id(id_surface);
	runner_assert(ivisurf != NULL);

	ctx->surface_property_changed.notify = test_surface_properties_changed_notification_callback;

	runner_assert(lyt->surface_add_listener(
		      ivisurf, &ctx->surface_property_changed) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(ctx->user_flags == 0);

	runner_assert(lyt->surface_set_destination_rectangle(
		      ivisurf, 20, 30, 200, 300) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(ctx->user_flags == 1);

	ctx->user_flags = 0;
	runner_assert(lyt->surface_set_destination_rectangle(
		      ivisurf, 20, 30, 200, 300) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(ctx->user_flags == 0);

	// remove surface property changed listener.
	wl_list_remove(&ctx->surface_property_changed.link);
	ctx->user_flags = 0;
	runner_assert(lyt->surface_set_destination_rectangle(
		      ivisurf, 40, 50, 400, 500) == IVI_SUCCEEDED);

	lyt->commit_changes();

	runner_assert(ctx->user_flags == 0);
}

static void
test_surface_configure_notification_callback(struct wl_listener *listener, void *data)
{
	struct test_context *ctx =
			container_of(listener, struct test_context,
					surface_configured);
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf = data;

	runner_assert_or_return(lyt->get_id_of_surface(ivisurf) == IVI_TEST_SURFACE_ID(0));

	ctx->user_flags = 1;
}

RUNNER_TEST(surface_configure_notification_p1)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;

	ctx->surface_configured.notify = test_surface_configure_notification_callback;
	runner_assert(IVI_SUCCEEDED == lyt->add_listener_configure_surface(&ctx->surface_configured));
	lyt->commit_changes();

	ctx->user_flags = 0;
}

RUNNER_TEST(surface_configure_notification_p2)
{
	runner_assert(ctx->user_flags == 1);

	// remove surface configured listener.
	wl_list_remove(&ctx->surface_configured.link);
	ctx->user_flags = 0;
}

RUNNER_TEST(surface_configure_notification_p3)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;

	lyt->commit_changes();
	runner_assert(ctx->user_flags == 0);
}

static void
test_surface_create_notification_callback(struct wl_listener *listener, void *data)
{
	struct test_context *ctx =
			container_of(listener, struct test_context,
					surface_created);
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf = data;

	runner_assert_or_return(lyt->get_id_of_surface(ivisurf) == IVI_TEST_SURFACE_ID(0));

	ctx->user_flags = 1;
}

RUNNER_TEST(surface_create_notification_p1)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;

	ctx->surface_created.notify = test_surface_create_notification_callback;
	runner_assert(lyt->add_listener_create_surface(
			&ctx->surface_created) == IVI_SUCCEEDED);

	ctx->user_flags = 0;
}

RUNNER_TEST(surface_create_notification_p2)
{
	runner_assert(ctx->user_flags == 1);

	// remove surface created listener.
	wl_list_remove(&ctx->surface_created.link);
	ctx->user_flags = 0;
}

RUNNER_TEST(surface_create_notification_p3)
{
	runner_assert(ctx->user_flags == 0);
}

static void
test_surface_remove_notification_callback(struct wl_listener *listener, void *data)
{
	struct test_context *ctx =
			container_of(listener, struct test_context,
					surface_removed);
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf = data;

	runner_assert_or_return(lyt->get_id_of_surface(ivisurf) == IVI_TEST_SURFACE_ID(0));

	ctx->user_flags = 1;
}

RUNNER_TEST(surface_remove_notification_p1)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;

	ctx->surface_removed.notify = test_surface_remove_notification_callback;
	runner_assert(lyt->add_listener_remove_surface(&ctx->surface_removed)
			== IVI_SUCCEEDED);

	ctx->user_flags = 0;
}

RUNNER_TEST(surface_remove_notification_p2)
{
	runner_assert(ctx->user_flags == 1);

	// remove surface removed listener.
	wl_list_remove(&ctx->surface_removed.link);
	ctx->user_flags = 0;
}

RUNNER_TEST(surface_remove_notification_p3)
{
	runner_assert(ctx->user_flags == 0);
}

static void
test_surface_bad_properties_changed_notification_callback(struct wl_listener *listener, void *data)
{
}

RUNNER_TEST(surface_bad_properties_changed_notification)
{
	const struct ivi_layout_interface *lyt = ctx->layout_interface;
	struct ivi_layout_surface *ivisurf;

	ivisurf = lyt->get_surface_from_id(IVI_TEST_SURFACE_ID(0));
	runner_assert(ivisurf != NULL);

	ctx->surface_property_changed.notify = test_surface_bad_properties_changed_notification_callback;

	runner_assert(lyt->surface_add_listener(
		      NULL, &ctx->surface_property_changed) == IVI_FAILED);
	runner_assert(lyt->surface_add_listener(
		      ivisurf, NULL) == IVI_FAILED);
}
