/*
 * Copyright © 2014 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>

#include "shared/helpers.h"
#include "shared/xalloc.h"
#include "weston-test-client-helper.h"
#include "presentation-time-client-protocol.h"

static struct wp_presentation *
get_presentation(struct client *client)
{
	struct global *g;
	struct global *global_pres = NULL;
	static struct wp_presentation *pres;

	if (pres)
		return pres;

	wl_list_for_each(g, &client->global_list, link) {
		if (strcmp(g->interface, wp_presentation_interface.name))
			continue;

		if (global_pres)
			assert(0 && "multiple presentation objects");

		global_pres = g;
	}

	assert(global_pres && "no presentation found");

	assert(global_pres->version == 1);

	pres = wl_registry_bind(client->wl_registry, global_pres->name,
				&wp_presentation_interface, 1);
	assert(pres);

	return pres;
}

struct feedback {
	struct client *client;
	struct wp_presentation_feedback *obj;

	enum {
		FB_PENDING = 0,
		FB_PRESENTED,
		FB_DISCARDED
	} result;

	struct wl_output *sync_output;
	uint64_t seq;
	struct timespec time;
	uint32_t refresh_nsec;
	uint32_t flags;
};

static void
timespec_from_proto(struct timespec *tm, uint32_t tv_sec_hi,
		    uint32_t tv_sec_lo, uint32_t tv_nsec)
{
	tm->tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
	tm->tv_nsec = tv_nsec;
}

static void
feedback_sync_output(void *data,
		     struct wp_presentation_feedback *presentation_feedback,
		     struct wl_output *output)
{
	struct feedback *fb = data;

	assert(fb->result == FB_PENDING);

	if (output)
		fb->sync_output = output;
}

static void
feedback_presented(void *data,
		   struct wp_presentation_feedback *presentation_feedback,
		   uint32_t tv_sec_hi,
		   uint32_t tv_sec_lo,
		   uint32_t tv_nsec,
		   uint32_t refresh_nsec,
		   uint32_t seq_hi,
		   uint32_t seq_lo,
		   uint32_t flags)
{
	struct feedback *fb = data;

	assert(fb->result == FB_PENDING);
	fb->result = FB_PRESENTED;
	fb->seq = ((uint64_t)seq_hi << 32) + seq_lo;
	timespec_from_proto(&fb->time, tv_sec_hi, tv_sec_lo, tv_nsec);
	fb->refresh_nsec = refresh_nsec;
	fb->flags = flags;
}

static void
feedback_discarded(void *data,
		   struct wp_presentation_feedback *presentation_feedback)
{
	struct feedback *fb = data;

	assert(fb->result == FB_PENDING);
	fb->result = FB_DISCARDED;
}

static const struct wp_presentation_feedback_listener feedback_listener = {
	feedback_sync_output,
	feedback_presented,
	feedback_discarded
};

static struct feedback *
feedback_create(struct client *client, struct wl_surface *surface)
{
	struct feedback *fb;

	fb = xzalloc(sizeof *fb);
	fb->client = client;
	fb->obj = wp_presentation_feedback(get_presentation(client), surface);
	wp_presentation_feedback_add_listener(fb->obj, &feedback_listener, fb);

	return fb;
}

static void
feedback_wait(struct feedback *fb)
{
	while (fb->result == FB_PENDING) {
		assert(wl_display_dispatch(fb->client->wl_display) >= 0);
	}
}

static char *
pflags_to_str(uint32_t flags, char *str, unsigned len)
{
	static const struct {
		uint32_t flag;
		char sym;
	} desc[] = {
		{ WP_PRESENTATION_FEEDBACK_KIND_VSYNC, 's' },
		{ WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK, 'c' },
		{ WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION, 'e' },
		{ WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY, 'z' },
	};
	unsigned i;

	*str = '\0';
	if (len < ARRAY_LENGTH(desc) + 1)
		return str;

	for (i = 0; i < ARRAY_LENGTH(desc); i++)
		str[i] = flags & desc[i].flag ? desc[i].sym : '_';
	str[ARRAY_LENGTH(desc)] = '\0';

	return str;
}

static void
feedback_print(struct feedback *fb)
{
	char str[10];

	switch (fb->result) {
	case FB_PENDING:
		printf("pending");
		return;
	case FB_DISCARDED:
		printf("discarded");
		return;
	case FB_PRESENTED:
		break;
	}

	pflags_to_str(fb->flags, str, sizeof str);
	printf("presented %lld.%09lld, refresh %u us, [%s] seq %" PRIu64,
		(long long)fb->time.tv_sec, (long long)fb->time.tv_nsec,
		fb->refresh_nsec / 1000, str, fb->seq);
}

static void
feedback_destroy(struct feedback *fb)
{
	wp_presentation_feedback_destroy(fb->obj);
	free(fb);
}

TEST(test_presentation_feedback_simple)
{
	struct client *client;
	struct feedback *fb;

	client = create_client_and_test_surface(100, 50, 123, 77);
	assert(client);

	wl_surface_attach(client->surface->wl_surface,
			  client->surface->buffer->proxy, 0, 0);
	fb = feedback_create(client, client->surface->wl_surface);
	wl_surface_damage(client->surface->wl_surface, 0, 0, 100, 100);
	wl_surface_commit(client->surface->wl_surface);

	client_roundtrip(client);

	feedback_wait(fb);

	printf("%s feedback:", __func__);
	feedback_print(fb);
	printf("\n");

	feedback_destroy(fb);
}
