/*
 * Copyright © 2012 Intel Corporation
 *
 * 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 <stdlib.h>
#include <string.h>
#include <linux/input.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/uio.h>

#include "compositor.h"
#include "shared/helpers.h"

struct clipboard_source {
	struct weston_data_source base;
	struct wl_array contents;
	struct clipboard *clipboard;
	struct wl_event_source *event_source;
	uint32_t serial;
	int refcount;
	int fd;
};

struct clipboard {
	struct weston_seat *seat;
	struct wl_listener selection_listener;
	struct wl_listener destroy_listener;
	struct clipboard_source *source;
};

static void clipboard_client_create(struct clipboard_source *source, int fd);

static void
clipboard_source_unref(struct clipboard_source *source)
{
	char **s;

	source->refcount--;
	if (source->refcount > 0)
		return;

	if (source->event_source) {
		wl_event_source_remove(source->event_source);
		close(source->fd);
	}
	wl_signal_emit(&source->base.destroy_signal,
		       &source->base);
	s = source->base.mime_types.data;
	free(*s);
	wl_array_release(&source->base.mime_types);
	wl_array_release(&source->contents);
	free(source);
}

static int
clipboard_source_data(int fd, uint32_t mask, void *data)
{
	struct clipboard_source *source = data;
	struct clipboard *clipboard = source->clipboard;
	char *p;
	int len, size;

	if (source->contents.alloc - source->contents.size < 1024) {
		wl_array_add(&source->contents, 1024);
		source->contents.size -= 1024;
	}

	p = source->contents.data + source->contents.size;
	size = source->contents.alloc - source->contents.size;
	len = read(fd, p, size);
	if (len == 0) {
		wl_event_source_remove(source->event_source);
		close(fd);
		source->event_source = NULL;
	} else if (len < 0) {
		clipboard_source_unref(source);
		clipboard->source = NULL;
	} else {
		source->contents.size += len;
	}

	return 1;
}

static void
clipboard_source_accept(struct weston_data_source *source,
			uint32_t time, const char *mime_type)
{
}

static void
clipboard_source_send(struct weston_data_source *base,
		      const char *mime_type, int32_t fd)
{
	struct clipboard_source *source =
		container_of(base, struct clipboard_source, base);
	char **s;

	s = source->base.mime_types.data;
	if (strcmp(mime_type, s[0]) == 0)
		clipboard_client_create(source, fd);
	else
		close(fd);
}

static void
clipboard_source_cancel(struct weston_data_source *source)
{
}

static struct clipboard_source *
clipboard_source_create(struct clipboard *clipboard,
			const char *mime_type, uint32_t serial, int fd)
{
	struct wl_display *display = clipboard->seat->compositor->wl_display;
	struct wl_event_loop *loop = wl_display_get_event_loop(display);
	struct clipboard_source *source;
	char **s;

	source = zalloc(sizeof *source);
	if (source == NULL)
		return NULL;

	wl_array_init(&source->contents);
	wl_array_init(&source->base.mime_types);
	source->base.resource = NULL;
	source->base.accept = clipboard_source_accept;
	source->base.send = clipboard_source_send;
	source->base.cancel = clipboard_source_cancel;
	wl_signal_init(&source->base.destroy_signal);
	source->refcount = 1;
	source->clipboard = clipboard;
	source->serial = serial;
	source->fd = fd;

	s = wl_array_add(&source->base.mime_types, sizeof *s);
	if (s == NULL)
		goto err_add;
	*s = strdup(mime_type);
	if (*s == NULL)
		goto err_strdup;
	source->event_source =
		wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
				     clipboard_source_data, source);
	if (source->event_source == NULL)
		goto err_source;

	return source;

 err_source:
	free(*s);
 err_strdup:
	wl_array_release(&source->base.mime_types);
 err_add:
	free(source);

	return NULL;
}

struct clipboard_client {
	struct wl_event_source *event_source;
	size_t offset;
	struct clipboard_source *source;
};

static int
clipboard_client_data(int fd, uint32_t mask, void *data)
{
	struct clipboard_client *client = data;
	char *p;
	size_t size;
	int len;

	size = client->source->contents.size;
	p = client->source->contents.data;
	len = write(fd, p + client->offset, size - client->offset);
	if (len > 0)
		client->offset += len;

	if (client->offset == size || len <= 0) {
		close(fd);
		wl_event_source_remove(client->event_source);
		clipboard_source_unref(client->source);
		free(client);
	}

	return 1;
}

static void
clipboard_client_create(struct clipboard_source *source, int fd)
{
	struct weston_seat *seat = source->clipboard->seat;
	struct clipboard_client *client;
	struct wl_event_loop *loop =
		wl_display_get_event_loop(seat->compositor->wl_display);

	client = zalloc(sizeof *client);
	if (client == NULL)
		return;

	client->source = source;
	source->refcount++;
	client->event_source =
		wl_event_loop_add_fd(loop, fd, WL_EVENT_WRITABLE,
				     clipboard_client_data, client);
}

static void
clipboard_set_selection(struct wl_listener *listener, void *data)
{
	struct clipboard *clipboard =
		container_of(listener, struct clipboard, selection_listener);
	struct weston_seat *seat = data;
	struct weston_data_source *source = seat->selection_data_source;
	const char **mime_types;
	int p[2];

	if (source == NULL) {
		if (clipboard->source)
			weston_seat_set_selection(seat,
						  &clipboard->source->base,
						  clipboard->source->serial);
		return;
	} else if (source->accept == clipboard_source_accept) {
		/* Callback for our data source. */
		return;
	}

	if (clipboard->source)
		clipboard_source_unref(clipboard->source);

	clipboard->source = NULL;

	mime_types = source->mime_types.data;

	if (!mime_types || pipe2(p, O_CLOEXEC) == -1)
		return;

	source->send(source, mime_types[0], p[1]);

	clipboard->source =
		clipboard_source_create(clipboard, mime_types[0],
					seat->selection_serial, p[0]);
	if (clipboard->source == NULL) {
		close(p[0]);
		return;
	}
}

static void
clipboard_destroy(struct wl_listener *listener, void *data)
{
	struct clipboard *clipboard =
		container_of(listener, struct clipboard, destroy_listener);

	wl_list_remove(&clipboard->selection_listener.link);
	wl_list_remove(&clipboard->destroy_listener.link);

	free(clipboard);
}

struct clipboard *
clipboard_create(struct weston_seat *seat)
{
	struct clipboard *clipboard;

	clipboard = zalloc(sizeof *clipboard);
	if (clipboard == NULL)
		return NULL;

	clipboard->seat = seat;
	clipboard->selection_listener.notify = clipboard_set_selection;
	clipboard->destroy_listener.notify = clipboard_destroy;

	wl_signal_add(&seat->selection_signal,
		      &clipboard->selection_listener);
	wl_signal_add(&seat->destroy_signal,
		      &clipboard->destroy_listener);

	return clipboard;
}
