/*
 * Copyright © 2013 David Herrmann
 *
 * 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 <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <systemd/sd-login.h>
#include <unistd.h>

#include "compositor.h"
#include "dbus.h"
#include "launcher-impl.h"

#define DRM_MAJOR 226

/* major()/minor() */
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#endif
#ifdef MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#endif

struct launcher_logind {
	struct weston_launcher base;
	struct weston_compositor *compositor;
	bool sync_drm;
	char *seat;
	char *sid;
	unsigned int vtnr;
	int vt;
	int kb_mode;

	DBusConnection *dbus;
	struct wl_event_source *dbus_ctx;
	char *spath;
	DBusPendingCall *pending_active;
};

static int
launcher_logind_take_device(struct launcher_logind *wl, uint32_t major,
			  uint32_t minor, bool *paused_out)
{
	DBusMessage *m, *reply;
	bool b;
	int r, fd;
	dbus_bool_t paused;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "TakeDevice");
	if (!m)
		return -ENOMEM;

	b = dbus_message_append_args(m,
				     DBUS_TYPE_UINT32, &major,
				     DBUS_TYPE_UINT32, &minor,
				     DBUS_TYPE_INVALID);
	if (!b) {
		r = -ENOMEM;
		goto err_unref;
	}

	reply = dbus_connection_send_with_reply_and_block(wl->dbus, m,
							  -1, NULL);
	if (!reply) {
		r = -ENODEV;
		goto err_unref;
	}

	b = dbus_message_get_args(reply, NULL,
				  DBUS_TYPE_UNIX_FD, &fd,
				  DBUS_TYPE_BOOLEAN, &paused,
				  DBUS_TYPE_INVALID);
	if (!b) {
		r = -ENODEV;
		goto err_reply;
	}

	r = fd;
	if (paused_out)
		*paused_out = paused;

err_reply:
	dbus_message_unref(reply);
err_unref:
	dbus_message_unref(m);
	return r;
}

static void
launcher_logind_release_device(struct launcher_logind *wl, uint32_t major,
			     uint32_t minor)
{
	DBusMessage *m;
	bool b;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "ReleaseDevice");
	if (m) {
		b = dbus_message_append_args(m,
					     DBUS_TYPE_UINT32, &major,
					     DBUS_TYPE_UINT32, &minor,
					     DBUS_TYPE_INVALID);
		if (b)
			dbus_connection_send(wl->dbus, m, NULL);
		dbus_message_unref(m);
	}
}

static void
launcher_logind_pause_device_complete(struct launcher_logind *wl, uint32_t major,
				    uint32_t minor)
{
	DBusMessage *m;
	bool b;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "PauseDeviceComplete");
	if (m) {
		b = dbus_message_append_args(m,
					     DBUS_TYPE_UINT32, &major,
					     DBUS_TYPE_UINT32, &minor,
					     DBUS_TYPE_INVALID);
		if (b)
			dbus_connection_send(wl->dbus, m, NULL);
		dbus_message_unref(m);
	}
}

static int
launcher_logind_open(struct weston_launcher *launcher, const char *path, int flags)
{
	struct launcher_logind *wl = wl_container_of(launcher, wl, base);
	struct stat st;
	int fl, r, fd;

	r = stat(path, &st);
	if (r < 0)
		return -1;
	if (!S_ISCHR(st.st_mode)) {
		errno = ENODEV;
		return -1;
	}

	fd = launcher_logind_take_device(wl, major(st.st_rdev),
				       minor(st.st_rdev), NULL);
	if (fd < 0)
		return fd;

	/* Compared to weston_launcher_open() we cannot specify the open-mode
	 * directly. Instead, logind passes us an fd with sane default modes.
	 * For DRM and evdev this means O_RDWR | O_CLOEXEC. If we want
	 * something else, we need to change it afterwards. We currently
	 * only support setting O_NONBLOCK. Changing access-modes is not
	 * possible so accept whatever logind passes us. */

	fl = fcntl(fd, F_GETFL);
	if (fl < 0) {
		r = -errno;
		goto err_close;
	}

	if (flags & O_NONBLOCK)
		fl |= O_NONBLOCK;

	r = fcntl(fd, F_SETFL, fl);
	if (r < 0) {
		r = -errno;
		goto err_close;
	}
	return fd;

err_close:
	close(fd);
	launcher_logind_release_device(wl, major(st.st_rdev),
				     minor(st.st_rdev));
	errno = -r;
	return -1;
}

static void
launcher_logind_close(struct weston_launcher *launcher, int fd)
{
	struct launcher_logind *wl = wl_container_of(launcher, wl, base);
	struct stat st;
	int r;

	r = fstat(fd, &st);
	close(fd);
	if (r < 0) {
		weston_log("logind: cannot fstat fd: %m\n");
		return;
	}

	if (!S_ISCHR(st.st_mode)) {
		weston_log("logind: invalid device passed\n");
		return;
	}

	launcher_logind_release_device(wl, major(st.st_rdev),
				     minor(st.st_rdev));
}

static int
launcher_logind_activate_vt(struct weston_launcher *launcher, int vt)
{
	struct launcher_logind *wl = wl_container_of(launcher, wl, base);
	DBusMessage *m;
	bool b;
	int r;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 "/org/freedesktop/login1/seat/self",
					 "org.freedesktop.login1.Seat",
					 "SwitchTo");
	if (!m)
		return -ENOMEM;

	b = dbus_message_append_args(m,
				     DBUS_TYPE_UINT32, &vt,
				     DBUS_TYPE_INVALID);
	if (!b) {
		r = -ENOMEM;
		goto err_unref;
	}

	dbus_connection_send(wl->dbus, m, NULL);
	r = 0;

 err_unref:
	dbus_message_unref(m);
	return r;
}

static void
launcher_logind_set_active(struct launcher_logind *wl, bool active)
{
	if (!wl->compositor->session_active == !active)
		return;

	wl->compositor->session_active = active;

	wl_signal_emit(&wl->compositor->session_signal,
		       wl->compositor);
}

static void
parse_active(struct launcher_logind *wl, DBusMessage *m, DBusMessageIter *iter)
{
	DBusMessageIter sub;
	dbus_bool_t b;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
		return;

	dbus_message_iter_recurse(iter, &sub);

	if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
		return;

	dbus_message_iter_get_basic(&sub, &b);

	/* If the backend requested DRM master-device synchronization, we only
	 * wake-up the compositor once the master-device is up and running. For
	 * other backends, we immediately forward the Active-change event. */
	if (!wl->sync_drm || !b)
		launcher_logind_set_active(wl, b);
}

static void
get_active_cb(DBusPendingCall *pending, void *data)
{
	struct launcher_logind *wl = data;
	DBusMessageIter iter;
	DBusMessage *m;
	int type;

	dbus_pending_call_unref(wl->pending_active);
	wl->pending_active = NULL;

	m = dbus_pending_call_steal_reply(pending);
	if (!m)
		return;

	type = dbus_message_get_type(m);
	if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN &&
	    dbus_message_iter_init(m, &iter))
		parse_active(wl, m, &iter);

	dbus_message_unref(m);
}

static void
launcher_logind_get_active(struct launcher_logind *wl)
{
	DBusPendingCall *pending;
	DBusMessage *m;
	bool b;
	const char *iface, *name;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.DBus.Properties",
					 "Get");
	if (!m)
		return;

	iface = "org.freedesktop.login1.Session";
	name = "Active";
	b = dbus_message_append_args(m,
				     DBUS_TYPE_STRING, &iface,
				     DBUS_TYPE_STRING, &name,
				     DBUS_TYPE_INVALID);
	if (!b)
		goto err_unref;

	b = dbus_connection_send_with_reply(wl->dbus, m, &pending, -1);
	if (!b)
		goto err_unref;

	b = dbus_pending_call_set_notify(pending, get_active_cb, wl, NULL);
	if (!b) {
		dbus_pending_call_cancel(pending);
		dbus_pending_call_unref(pending);
		goto err_unref;
	}

	if (wl->pending_active) {
		dbus_pending_call_cancel(wl->pending_active);
		dbus_pending_call_unref(wl->pending_active);
	}
	wl->pending_active = pending;
	return;

err_unref:
	dbus_message_unref(m);
}

static void
disconnected_dbus(struct launcher_logind *wl)
{
	weston_log("logind: dbus connection lost, exiting..\n");
	exit(-1);
}

static void
session_removed(struct launcher_logind *wl, DBusMessage *m)
{
	const char *name, *obj;
	bool r;

	r = dbus_message_get_args(m, NULL,
				  DBUS_TYPE_STRING, &name,
				  DBUS_TYPE_OBJECT_PATH, &obj,
				  DBUS_TYPE_INVALID);
	if (!r) {
		weston_log("logind: cannot parse SessionRemoved dbus signal\n");
		return;
	}

	if (!strcmp(name, wl->sid)) {
		weston_log("logind: our session got closed, exiting..\n");
		exit(-1);
	}
}

static void
property_changed(struct launcher_logind *wl, DBusMessage *m)
{
	DBusMessageIter iter, sub, entry;
	const char *interface, *name;

	if (!dbus_message_iter_init(m, &iter) ||
	    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		goto error;

	dbus_message_iter_get_basic(&iter, &interface);

	if (!dbus_message_iter_next(&iter) ||
	    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		goto error;

	dbus_message_iter_recurse(&iter, &sub);

	while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY) {
		dbus_message_iter_recurse(&sub, &entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
			goto error;

		dbus_message_iter_get_basic(&entry, &name);
		if (!dbus_message_iter_next(&entry))
			goto error;

		if (!strcmp(name, "Active")) {
			parse_active(wl, m, &entry);
			return;
		}

		dbus_message_iter_next(&sub);
	}

	if (!dbus_message_iter_next(&iter) ||
	    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		goto error;

	dbus_message_iter_recurse(&iter, &sub);

	while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
		dbus_message_iter_get_basic(&sub, &name);

		if (!strcmp(name, "Active")) {
			launcher_logind_get_active(wl);
			return;
		}

		dbus_message_iter_next(&sub);
	}

	return;

error:
	weston_log("logind: cannot parse PropertiesChanged dbus signal\n");
}

static void
device_paused(struct launcher_logind *wl, DBusMessage *m)
{
	bool r;
	const char *type;
	uint32_t major, minor;

	r = dbus_message_get_args(m, NULL,
				  DBUS_TYPE_UINT32, &major,
				  DBUS_TYPE_UINT32, &minor,
				  DBUS_TYPE_STRING, &type,
				  DBUS_TYPE_INVALID);
	if (!r) {
		weston_log("logind: cannot parse PauseDevice dbus signal\n");
		return;
	}

	/* "pause" means synchronous pausing. Acknowledge it unconditionally
	 * as we support asynchronous device shutdowns, anyway.
	 * "force" means asynchronous pausing.
	 * "gone" means the device is gone. We handle it the same as "force" as
	 * a following udev event will be caught, too.
	 *
	 * If it's our main DRM device and not "gone", tell the compositor to go asleep. */
	if (!strcmp(type, "pause"))
		launcher_logind_pause_device_complete(wl, major, minor);
	else if (strcmp(type, "gone") == 0)
		return;

	if (wl->sync_drm && major == DRM_MAJOR)
		launcher_logind_set_active(wl, false);
}

static void
device_resumed(struct launcher_logind *wl, DBusMessage *m)
{
	bool r;
	uint32_t major;

	r = dbus_message_get_args(m, NULL,
				  DBUS_TYPE_UINT32, &major,
				  /*DBUS_TYPE_UINT32, &minor,
				  DBUS_TYPE_UNIX_FD, &fd,*/
				  DBUS_TYPE_INVALID);
	if (!r) {
		weston_log("logind: cannot parse ResumeDevice dbus signal\n");
		return;
	}

	/* DeviceResumed messages provide us a new file-descriptor for
	 * resumed devices. For DRM devices it's the same as before, for evdev
	 * devices it's a new open-file. As we reopen evdev devices, anyway,
	 * there is no need for us to handle this event for evdev. For DRM, we
	 * notify the compositor to wake up. */

	if (wl->sync_drm && major == DRM_MAJOR)
		launcher_logind_set_active(wl, true);
}

static DBusHandlerResult
filter_dbus(DBusConnection *c, DBusMessage *m, void *data)
{
	struct launcher_logind *wl = data;

	if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) {
		disconnected_dbus(wl);
	} else if (dbus_message_is_signal(m, "org.freedesktop.login1.Manager",
					  "SessionRemoved")) {
		session_removed(wl, m);
	} else if (dbus_message_is_signal(m, "org.freedesktop.DBus.Properties",
					  "PropertiesChanged")) {
		property_changed(wl, m);
	} else if (dbus_message_is_signal(m, "org.freedesktop.login1.Session",
					  "PauseDevice")) {
		device_paused(wl, m);
	} else if (dbus_message_is_signal(m, "org.freedesktop.login1.Session",
					  "ResumeDevice")) {
		device_resumed(wl, m);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static int
launcher_logind_setup_dbus(struct launcher_logind *wl)
{
	bool b;
	int r;

	r = asprintf(&wl->spath, "/org/freedesktop/login1/session/%s",
		     wl->sid);
	if (r < 0)
		return -ENOMEM;

	b = dbus_connection_add_filter(wl->dbus, filter_dbus, wl, NULL);
	if (!b) {
		weston_log("logind: cannot add dbus filter\n");
		r = -ENOMEM;
		goto err_spath;
	}

	r = weston_dbus_add_match_signal(wl->dbus,
					 "org.freedesktop.login1",
					 "org.freedesktop.login1.Manager",
					 "SessionRemoved",
					 "/org/freedesktop/login1");
	if (r < 0) {
		weston_log("logind: cannot add dbus match\n");
		goto err_spath;
	}

	r = weston_dbus_add_match_signal(wl->dbus,
					"org.freedesktop.login1",
					"org.freedesktop.login1.Session",
					"PauseDevice",
					wl->spath);
	if (r < 0) {
		weston_log("logind: cannot add dbus match\n");
		goto err_spath;
	}

	r = weston_dbus_add_match_signal(wl->dbus,
					"org.freedesktop.login1",
					"org.freedesktop.login1.Session",
					"ResumeDevice",
					wl->spath);
	if (r < 0) {
		weston_log("logind: cannot add dbus match\n");
		goto err_spath;
	}

	r = weston_dbus_add_match_signal(wl->dbus,
					"org.freedesktop.login1",
					"org.freedesktop.DBus.Properties",
					"PropertiesChanged",
					wl->spath);
	if (r < 0) {
		weston_log("logind: cannot add dbus match\n");
		goto err_spath;
	}

	return 0;

err_spath:
	/* don't remove any dbus-match as the connection is closed, anyway */
	free(wl->spath);
	return r;
}

static void
launcher_logind_destroy_dbus(struct launcher_logind *wl)
{
	/* don't remove any dbus-match as the connection is closed, anyway */
	free(wl->spath);
}

static int
launcher_logind_take_control(struct launcher_logind *wl)
{
	DBusError err;
	DBusMessage *m, *reply;
	dbus_bool_t force;
	bool b;
	int r;

	dbus_error_init(&err);

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "TakeControl");
	if (!m)
		return -ENOMEM;

	force = false;
	b = dbus_message_append_args(m,
				     DBUS_TYPE_BOOLEAN, &force,
				     DBUS_TYPE_INVALID);
	if (!b) {
		r = -ENOMEM;
		goto err_unref;
	}

	reply = dbus_connection_send_with_reply_and_block(wl->dbus,
							  m, -1, &err);
	if (!reply) {
		if (dbus_error_has_name(&err, DBUS_ERROR_UNKNOWN_METHOD))
			weston_log("logind: old systemd version detected\n");
		else
			weston_log("logind: cannot take control over session %s\n", wl->sid);

		dbus_error_free(&err);
		r = -EIO;
		goto err_unref;
	}

	dbus_message_unref(reply);
	dbus_message_unref(m);
	return 0;

err_unref:
	dbus_message_unref(m);
	return r;
}

static void
launcher_logind_release_control(struct launcher_logind *wl)
{
	DBusMessage *m;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "ReleaseControl");
	if (m) {
		dbus_connection_send(wl->dbus, m, NULL);
		dbus_message_unref(m);
	}
}

static int
weston_sd_session_get_vt(const char *sid, unsigned int *out)
{
#ifdef HAVE_SYSTEMD_LOGIN_209
	return sd_session_get_vt(sid, out);
#else
	int r;
	char *tty;

	r = sd_session_get_tty(sid, &tty);
	if (r < 0)
		return r;

	r = sscanf(tty, "tty%u", out);
	free(tty);

	if (r != 1)
		return -EINVAL;

	return 0;
#endif
}

static int
launcher_logind_activate(struct launcher_logind *wl)
{
	DBusMessage *m;

	m = dbus_message_new_method_call("org.freedesktop.login1",
					 wl->spath,
					 "org.freedesktop.login1.Session",
					 "Activate");
	if (!m)
		return -ENOMEM;

	dbus_connection_send(wl->dbus, m, NULL);
	return 0;
}

static int
launcher_logind_connect(struct weston_launcher **out, struct weston_compositor *compositor,
			int tty, const char *seat_id, bool sync_drm)
{
	struct launcher_logind *wl;
	struct wl_event_loop *loop;
	char *t;
	int r;

	wl = zalloc(sizeof(*wl));
	if (wl == NULL) {
		r = -ENOMEM;
		goto err_out;
	}

	wl->base.iface = &launcher_logind_iface;
	wl->compositor = compositor;
	wl->sync_drm = sync_drm;

	wl->seat = strdup(seat_id);
	if (!wl->seat) {
		r = -ENOMEM;
		goto err_wl;
	}

	r = sd_pid_get_session(getpid(), &wl->sid);
	if (r < 0) {
		weston_log("logind: not running in a systemd session\n");
		goto err_seat;
	}

	t = NULL;
	r = sd_session_get_seat(wl->sid, &t);
	if (r < 0) {
		weston_log("logind: failed to get session seat\n");
		free(t);
		goto err_session;
	} else if (strcmp(seat_id, t)) {
		weston_log("logind: weston's seat '%s' differs from session-seat '%s'\n",
			   seat_id, t);
		r = -EINVAL;
		free(t);
		goto err_session;
	}

	r = strcmp(t, "seat0");
	free(t);
	if (r == 0) {
		r = weston_sd_session_get_vt(wl->sid, &wl->vtnr);
		if (r < 0) {
			weston_log("logind: session not running on a VT\n");
			goto err_session;
		} else if (tty > 0 && wl->vtnr != (unsigned int )tty) {
			weston_log("logind: requested VT --tty=%d differs from real session VT %u\n",
				   tty, wl->vtnr);
			r = -EINVAL;
			goto err_session;
		}
	}

	loop = wl_display_get_event_loop(compositor->wl_display);
	r = weston_dbus_open(loop, DBUS_BUS_SYSTEM, &wl->dbus, &wl->dbus_ctx);
	if (r < 0) {
		weston_log("logind: cannot connect to system dbus\n");
		goto err_session;
	}

	r = launcher_logind_setup_dbus(wl);
	if (r < 0)
		goto err_dbus;

	r = launcher_logind_take_control(wl);
	if (r < 0)
		goto err_dbus_cleanup;

	r = launcher_logind_activate(wl);
	if (r < 0)
		goto err_dbus_cleanup;

	weston_log("logind: session control granted\n");
	* (struct launcher_logind **) out = wl;
	return 0;

err_dbus_cleanup:
	launcher_logind_destroy_dbus(wl);
err_dbus:
	weston_dbus_close(wl->dbus, wl->dbus_ctx);
err_session:
	free(wl->sid);
err_seat:
	free(wl->seat);
err_wl:
	free(wl);
err_out:
	weston_log("logind: cannot setup systemd-logind helper (%d), using legacy fallback\n", r);
	errno = -r;
	return -1;
}

static void
launcher_logind_destroy(struct weston_launcher *launcher)
{
	struct launcher_logind *wl = wl_container_of(launcher, wl, base);

	if (wl->pending_active) {
		dbus_pending_call_cancel(wl->pending_active);
		dbus_pending_call_unref(wl->pending_active);
	}

	launcher_logind_release_control(wl);
	launcher_logind_destroy_dbus(wl);
	weston_dbus_close(wl->dbus, wl->dbus_ctx);
	free(wl->sid);
	free(wl->seat);
	free(wl);
}

static int
launcher_logind_get_vt(struct weston_launcher *launcher)
{
	struct launcher_logind *wl = wl_container_of(launcher, wl, base);
	return wl->vtnr;
}

const struct launcher_interface launcher_logind_iface = {
	.connect = launcher_logind_connect,
	.destroy = launcher_logind_destroy,
	.open = launcher_logind_open,
	.close = launcher_logind_close,
	.activate_vt = launcher_logind_activate_vt,
	.get_vt = launcher_logind_get_vt,
};
