/*
 * Copyright © 2013 Intel Corporation
 * Copyright © 2013 Jonas Ådahl
 *
 * 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 <unistd.h>
#include <fcntl.h>
#include <libinput.h>
#include <libudev.h>

#include "compositor.h"
#include "launcher-util.h"
#include "libinput-seat.h"
#include "libinput-device.h"
#include "shared/helpers.h"

static void
process_events(struct udev_input *input);
static struct udev_seat *
udev_seat_create(struct udev_input *input, const char *seat_name);
static void
udev_seat_destroy(struct udev_seat *seat);

static struct udev_seat *
get_udev_seat(struct udev_input *input, struct libinput_device *device)
{
	struct libinput_seat *libinput_seat;
	const char *seat_name;

	libinput_seat = libinput_device_get_seat(device);
	seat_name = libinput_seat_get_logical_name(libinput_seat);
	return udev_seat_get_named(input, seat_name);
}

static struct weston_output *
output_find_by_head_name(struct weston_compositor *compositor,
			 const char *head_name)
{
	struct weston_output *output;
	struct weston_head *head;

	if (!head_name)
		return NULL;

	/* Only enabled outputs with connected heads.
	 * This means force-enabled outputs but with disconnected heads
	 * will be ignored; if the touchscreen doesn't have a video signal,
	 * touching it is meaningless.
	 */
	wl_list_for_each(output, &compositor->output_list, link) {
		wl_list_for_each(head, &output->head_list, output_link) {
			if (!weston_head_is_connected(head))
				continue;

			if (strcmp(head_name, head->name) == 0)
				return output;
		}
	}

	return NULL;
}

static void
device_added(struct udev_input *input, struct libinput_device *libinput_device)
{
	struct weston_compositor *c;
	struct evdev_device *device;
	struct weston_output *output;
	const char *output_name;
	struct weston_seat *seat;
	struct udev_seat *udev_seat;
	struct weston_pointer *pointer;

	c = input->compositor;

	udev_seat = get_udev_seat(input, libinput_device);
	if (!udev_seat)
		return;

	seat = &udev_seat->base;
	device = evdev_device_create(libinput_device, seat);
	if (device == NULL)
		return;

	if (input->configure_device != NULL)
		input->configure_device(c, device->device);
	evdev_device_set_calibration(device);
	udev_seat = (struct udev_seat *) seat;
	wl_list_insert(udev_seat->devices_list.prev, &device->link);

	pointer = weston_seat_get_pointer(seat);
	if (seat->output && pointer)
		weston_pointer_clamp(pointer,
				     &pointer->x,
				     &pointer->y);

	output_name = libinput_device_get_output_name(libinput_device);
	if (output_name) {
		device->output_name = strdup(output_name);
		output = output_find_by_head_name(c, output_name);
		evdev_device_set_output(device, output);
	} else if (!wl_list_empty(&c->output_list)) {
		/* default assignment to an arbitrary output */
		output = container_of(c->output_list.next,
				      struct weston_output, link);
		evdev_device_set_output(device, output);
	}

	if (!input->suspended)
		weston_seat_repick(seat);
}

static void
device_removed(struct udev_input *input, struct libinput_device *libinput_device)
{
	struct evdev_device *device;

	device = libinput_device_get_user_data(libinput_device);
	evdev_device_destroy(device);
}

static void
udev_seat_remove_devices(struct udev_seat *seat)
{
	struct evdev_device *device, *next;

	wl_list_for_each_safe(device, next, &seat->devices_list, link) {
		evdev_device_destroy(device);
	}
}

void
udev_input_disable(struct udev_input *input)
{
	if (input->suspended)
		return;

	wl_event_source_remove(input->libinput_source);
	input->libinput_source = NULL;
	libinput_suspend(input->libinput);
	process_events(input);
	input->suspended = 1;
}

static int
udev_input_process_event(struct libinput_event *event)
{
	struct libinput *libinput = libinput_event_get_context(event);
	struct libinput_device *libinput_device =
		libinput_event_get_device(event);
	struct udev_input *input = libinput_get_user_data(libinput);
	int handled = 1;

	switch (libinput_event_get_type(event)) {
	case LIBINPUT_EVENT_DEVICE_ADDED:
		device_added(input, libinput_device);
		break;
	case LIBINPUT_EVENT_DEVICE_REMOVED:
		device_removed(input, libinput_device);
		break;
	default:
		handled = 0;
	}

	return handled;
}

static void
process_event(struct libinput_event *event)
{
	if (udev_input_process_event(event))
		return;
	if (evdev_device_process_event(event))
		return;
}

static void
process_events(struct udev_input *input)
{
	struct libinput_event *event;

	while ((event = libinput_get_event(input->libinput))) {
		process_event(event);
		libinput_event_destroy(event);
	}
}

static int
udev_input_dispatch(struct udev_input *input)
{
	if (libinput_dispatch(input->libinput) != 0)
		weston_log("libinput: Failed to dispatch libinput\n");

	process_events(input);

	return 0;
}

static int
libinput_source_dispatch(int fd, uint32_t mask, void *data)
{
	struct udev_input *input = data;

	return udev_input_dispatch(input) != 0;
}

static int
open_restricted(const char *path, int flags, void *user_data)
{
	struct udev_input *input = user_data;
	struct weston_launcher *launcher = input->compositor->launcher;

	return weston_launcher_open(launcher, path, flags);
}

static void
close_restricted(int fd, void *user_data)
{
	struct udev_input *input = user_data;
	struct weston_launcher *launcher = input->compositor->launcher;

	weston_launcher_close(launcher, fd);
}

const struct libinput_interface libinput_interface = {
	open_restricted,
	close_restricted,
};

int
udev_input_enable(struct udev_input *input)
{
	struct wl_event_loop *loop;
	struct weston_compositor *c = input->compositor;
	int fd;
	struct udev_seat *seat;
	int devices_found = 0;

	loop = wl_display_get_event_loop(c->wl_display);
	fd = libinput_get_fd(input->libinput);
	input->libinput_source =
		wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
				     libinput_source_dispatch, input);
	if (!input->libinput_source) {
		return -1;
	}

	if (input->suspended) {
		if (libinput_resume(input->libinput) != 0) {
			wl_event_source_remove(input->libinput_source);
			input->libinput_source = NULL;
			return -1;
		}
		input->suspended = 0;
		process_events(input);
	}

	wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
		evdev_notify_keyboard_focus(&seat->base, &seat->devices_list);

		if (!wl_list_empty(&seat->devices_list))
			devices_found = 1;
	}

	if (devices_found == 0 && !c->require_input) {
		weston_log("warning: no input devices found, but none required "
			   "as per configuration.\n");
		return 0;
	}

	if (devices_found == 0) {
		weston_log(
			"warning: no input devices on entering Weston. "
			"Possible causes:\n"
			"\t- no permissions to read /dev/input/event*\n"
			"\t- seats misconfigured "
			"(Weston backend option 'seat', "
			"udev device property ID_SEAT)\n");
		return -1;
	}

	return 0;
}

static void
libinput_log_func(struct libinput *libinput,
		  enum libinput_log_priority priority,
		  const char *format, va_list args)
{
	weston_vlog(format, args);
}

int
udev_input_init(struct udev_input *input, struct weston_compositor *c,
		struct udev *udev, const char *seat_id,
		udev_configure_device_t configure_device)
{
	enum libinput_log_priority priority = LIBINPUT_LOG_PRIORITY_INFO;
	const char *log_priority = NULL;

	memset(input, 0, sizeof *input);

	input->compositor = c;
	input->configure_device = configure_device;

	log_priority = getenv("WESTON_LIBINPUT_LOG_PRIORITY");

	input->libinput = libinput_udev_create_context(&libinput_interface,
						       input, udev);
	if (!input->libinput) {
		return -1;
	}

	libinput_log_set_handler(input->libinput, &libinput_log_func);

	if (log_priority) {
		if (strcmp(log_priority, "debug") == 0) {
			priority = LIBINPUT_LOG_PRIORITY_DEBUG;
		} else if (strcmp(log_priority, "info") == 0) {
			priority = LIBINPUT_LOG_PRIORITY_INFO;
		} else if (strcmp(log_priority, "error") == 0) {
			priority = LIBINPUT_LOG_PRIORITY_ERROR;
		}
	}

	libinput_log_set_priority(input->libinput, priority);

	if (libinput_udev_assign_seat(input->libinput, seat_id) != 0) {
		libinput_unref(input->libinput);
		return -1;
	}

	process_events(input);

	return udev_input_enable(input);
}

void
udev_input_destroy(struct udev_input *input)
{
	struct udev_seat *seat, *next;

	if (input->libinput_source)
		wl_event_source_remove(input->libinput_source);
	wl_list_for_each_safe(seat, next, &input->compositor->seat_list, base.link)
		udev_seat_destroy(seat);
	libinput_unref(input->libinput);
}

static void
udev_seat_led_update(struct weston_seat *seat_base, enum weston_led leds)
{
	struct udev_seat *seat = (struct udev_seat *) seat_base;
	struct evdev_device *device;

	wl_list_for_each(device, &seat->devices_list, link)
		evdev_led_update(device, leds);
}

static void
udev_seat_output_changed(struct udev_seat *seat, struct weston_output *output)
{
	struct evdev_device *device;
	struct weston_output *found;

	wl_list_for_each(device, &seat->devices_list, link) {
		/* If we find any input device without an associated output
		 * or an output name to associate with, just tie it with the
		 * output we got here - the default assingment.
		 */
		if (!device->output_name) {
			if (!device->output)
				evdev_device_set_output(device, output);

			continue;
		}

		/* Update all devices' output associations, may they gain or
		 * lose it.
		 */
		found = output_find_by_head_name(output->compositor,
						 device->output_name);
		evdev_device_set_output(device, found);
	}
}

static void
notify_output_create(struct wl_listener *listener, void *data)
{
	struct udev_seat *seat = container_of(listener, struct udev_seat,
					      output_create_listener);
	struct weston_output *output = data;

	udev_seat_output_changed(seat, output);
}

static void
notify_output_heads_changed(struct wl_listener *listener, void *data)
{
	struct udev_seat *seat = container_of(listener, struct udev_seat,
					      output_heads_listener);
	struct weston_output *output = data;

	udev_seat_output_changed(seat, output);
}

static struct udev_seat *
udev_seat_create(struct udev_input *input, const char *seat_name)
{
	struct weston_compositor *c = input->compositor;
	struct udev_seat *seat;

	seat = zalloc(sizeof *seat);
	if (!seat)
		return NULL;

	weston_seat_init(&seat->base, c, seat_name);
	seat->base.led_update = udev_seat_led_update;

	seat->output_create_listener.notify = notify_output_create;
	wl_signal_add(&c->output_created_signal,
		      &seat->output_create_listener);

	seat->output_heads_listener.notify = notify_output_heads_changed;
	wl_signal_add(&c->output_heads_changed_signal,
		      &seat->output_heads_listener);

	wl_list_init(&seat->devices_list);

	return seat;
}

static void
udev_seat_destroy(struct udev_seat *seat)
{
	struct weston_keyboard *keyboard =
		weston_seat_get_keyboard(&seat->base);

	if (keyboard)
		notify_keyboard_focus_out(&seat->base);

	udev_seat_remove_devices(seat);
	weston_seat_release(&seat->base);
	wl_list_remove(&seat->output_create_listener.link);
	wl_list_remove(&seat->output_heads_listener.link);
	free(seat);
}

struct udev_seat *
udev_seat_get_named(struct udev_input *input, const char *seat_name)
{
	struct udev_seat *seat;

	wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
		if (strcmp(seat->base.seat_name, seat_name) == 0)
			return seat;
	}

	return udev_seat_create(input, seat_name);
}
