/*
 * Copyright © 2013 Richard Hughes
 *
 * 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 <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <colord.h>

#include "compositor.h"
#include "weston.h"
#include "cms-helper.h"
#include "shared/helpers.h"

struct cms_colord {
	struct weston_compositor	*ec;
	CdClient			*client;
	GHashTable			*devices; /* key = device-id, value = cms_output */
	GHashTable			*pnp_ids; /* key = pnp-id, value = vendor */
	gchar				*pnp_ids_data;
	GMainLoop			*loop;
	GThread				*thread;
	GList				*pending;
	GMutex				 pending_mutex;
	struct wl_event_source		*source;
	int				 readfd;
	int				 writefd;
	struct wl_listener		 destroy_listener;
	struct wl_listener		 output_created_listener;
};

struct cms_output {
	CdDevice			*device;
	guint32				 backlight_value;
	struct cms_colord		*cms;
	struct weston_color_profile	*p;
	struct weston_output		*o;
	struct wl_listener		 destroy_listener;
};

static gint
colord_idle_find_output_cb(gconstpointer a, gconstpointer b)
{
	struct cms_output *ocms = (struct cms_output *) a;
	struct weston_output *o = (struct weston_output *) b;
	return ocms->o == o ? 0 : -1;
}

static void
colord_idle_cancel_for_output(struct cms_colord *cms, struct weston_output *o)
{
	GList *l;

	/* cancel and remove any helpers that match the output */
	g_mutex_lock(&cms->pending_mutex);
	l = g_list_find_custom (cms->pending, o, colord_idle_find_output_cb);
	if (l) {
		struct cms_output *ocms = l->data;
		cms->pending = g_list_remove (cms->pending, ocms);
	}
	g_mutex_unlock(&cms->pending_mutex);
}

static bool
edid_value_valid(const char *str)
{
	if (str == NULL)
		return false;
	if (str[0] == '\0')
		return false;
	if (strcmp(str, "unknown") == 0)
		return false;
	return true;
}

static gchar *
get_output_id(struct cms_colord *cms, struct weston_output *o)
{
	const gchar *tmp;
	GString *device_id;

	/* see https://github.com/hughsie/colord/blob/master/doc/device-and-profile-naming-spec.txt
	 * for format and allowed values */
	device_id = g_string_new("xrandr");
	if (edid_value_valid(o->make)) {
		tmp = g_hash_table_lookup(cms->pnp_ids, o->make);
		if (tmp == NULL)
			tmp = o->make;
		g_string_append_printf(device_id, "-%s", tmp);
	}
	if (edid_value_valid(o->model))
		g_string_append_printf(device_id, "-%s", o->model);
	if (edid_value_valid(o->serial_number))
		g_string_append_printf(device_id, "-%s", o->serial_number);

	/* no EDID data, so use fallback */
	if (strcmp(device_id->str, "xrandr") == 0)
		g_string_append_printf(device_id, "-drm-%i", o->id);

	return g_string_free(device_id, FALSE);
}

static void
update_device_with_profile_in_idle(struct cms_output *ocms)
{
	gboolean signal_write = FALSE;
	ssize_t rc;
	struct cms_colord *cms = ocms->cms;

	colord_idle_cancel_for_output(cms, ocms->o);
	g_mutex_lock(&cms->pending_mutex);
	if (cms->pending == NULL)
		signal_write = TRUE;
	cms->pending = g_list_prepend(cms->pending, ocms);
	g_mutex_unlock(&cms->pending_mutex);

	/* signal we've got updates to do */
	if (signal_write) {
		gchar tmp = '\0';
		rc = write(cms->writefd, &tmp, 1);
		if (rc == 0)
			weston_log("colord: failed to write to pending fd\n");
	}
}

static void
colord_update_output_from_device (struct cms_output *ocms)
{
	CdProfile *profile;
	const gchar *tmp;
	gboolean ret;
	GError *error = NULL;
	gint percentage;

	/* old profile is no longer valid */
	weston_cms_destroy_profile(ocms->p);
	ocms->p = NULL;

	ret = cd_device_connect_sync(ocms->device, NULL, &error);
	if (!ret) {
		weston_log("colord: failed to connect to device %s: %s\n",
			   cd_device_get_object_path (ocms->device),
			   error->message);
		g_error_free(error);
		goto out;
	}
	profile = cd_device_get_default_profile(ocms->device);
	if (!profile) {
		weston_log("colord: no assigned color profile for %s\n",
			   cd_device_get_id (ocms->device));
		goto out;
	}
	ret = cd_profile_connect_sync(profile, NULL, &error);
	if (!ret) {
		weston_log("colord: failed to connect to profile %s: %s\n",
			   cd_profile_get_object_path (profile),
			   error->message);
		g_error_free(error);
		goto out;
	}

	/* get the calibration brightness level (only set for some profiles) */
	tmp = cd_profile_get_metadata_item(profile, CD_PROFILE_METADATA_SCREEN_BRIGHTNESS);
	if (tmp != NULL) {
		percentage = atoi(tmp);
		if (percentage > 0 && percentage <= 100)
			ocms->backlight_value = percentage * 255 / 100;
	}

	ocms->p = weston_cms_load_profile(cd_profile_get_filename(profile));
	if (ocms->p == NULL) {
		weston_log("colord: warning failed to load profile %s: %s\n",
			   cd_profile_get_object_path (profile),
			   error->message);
		g_error_free(error);
		goto out;
	}
out:
	update_device_with_profile_in_idle(ocms);
}

static void
colord_device_changed_cb(CdDevice *device, struct cms_output *ocms)
{
	weston_log("colord: device %s changed, update output\n",
		   cd_device_get_object_path (ocms->device));
	colord_update_output_from_device(ocms);
}

static void
colord_notifier_output_destroy(struct wl_listener *listener, void *data)
{
	struct cms_output *ocms =
		container_of(listener, struct cms_output, destroy_listener);
	struct weston_output *o = (struct weston_output *) data;
	struct cms_colord *cms = ocms->cms;
	gchar *device_id;

	device_id = get_output_id(cms, o);
	g_hash_table_remove (cms->devices, device_id);
	g_free (device_id);
}

static void
colord_output_created(struct cms_colord *cms, struct weston_output *o)
{
	CdDevice *device;
	const gchar *tmp;
	gchar *device_id;
	GError *error = NULL;
	GHashTable *device_props;
	struct cms_output *ocms;

	/* create device */
	device_id = get_output_id(cms, o);
	weston_log("colord: output added %s\n", device_id);
	device_props = g_hash_table_new_full(g_str_hash, g_str_equal,
					     g_free, g_free);
	g_hash_table_insert (device_props,
			     g_strdup(CD_DEVICE_PROPERTY_KIND),
			     g_strdup(cd_device_kind_to_string (CD_DEVICE_KIND_DISPLAY)));
	g_hash_table_insert (device_props,
			     g_strdup(CD_DEVICE_PROPERTY_FORMAT),
			     g_strdup("ColorModel.OutputMode.OutputResolution"));
	g_hash_table_insert (device_props,
			     g_strdup(CD_DEVICE_PROPERTY_COLORSPACE),
			     g_strdup(cd_colorspace_to_string(CD_COLORSPACE_RGB)));
	if (edid_value_valid(o->make)) {
		tmp = g_hash_table_lookup(cms->pnp_ids, o->make);
		if (tmp == NULL)
			tmp = o->make;
		g_hash_table_insert (device_props,
				     g_strdup(CD_DEVICE_PROPERTY_VENDOR),
				     g_strdup(tmp));
	}
	if (edid_value_valid(o->model)) {
		g_hash_table_insert (device_props,
				     g_strdup(CD_DEVICE_PROPERTY_MODEL),
				     g_strdup(o->model));
	}
	if (edid_value_valid(o->serial_number)) {
		g_hash_table_insert (device_props,
				     g_strdup(CD_DEVICE_PROPERTY_SERIAL),
				     g_strdup(o->serial_number));
	}
	if (o->connection_internal) {
		g_hash_table_insert (device_props,
				     g_strdup (CD_DEVICE_PROPERTY_EMBEDDED),
				     NULL);
	}
	device = cd_client_create_device_sync(cms->client,
					      device_id,
					      CD_OBJECT_SCOPE_TEMP,
					      device_props,
					      NULL,
					      &error);
	if (g_error_matches (error,
			     CD_CLIENT_ERROR,
			     CD_CLIENT_ERROR_ALREADY_EXISTS)) {
		g_clear_error(&error);
		device = cd_client_find_device_sync (cms->client,
						     device_id,
						     NULL,
						     &error);
	}
	if (!device) {
		weston_log("colord: failed to create new or "
			   "find existing device: %s\n",
			   error->message);
		g_error_free(error);
		goto out;
	}

	/* create object and watch for the output to be destroyed */
	ocms = g_slice_new0(struct cms_output);
	ocms->cms = cms;
	ocms->o = o;
	ocms->device = g_object_ref(device);
	ocms->destroy_listener.notify = colord_notifier_output_destroy;
	wl_signal_add(&o->destroy_signal, &ocms->destroy_listener);

	/* add to local cache */
	g_hash_table_insert (cms->devices, g_strdup(device_id), ocms);
	g_signal_connect (ocms->device, "changed",
			  G_CALLBACK (colord_device_changed_cb), ocms);

	/* get profiles */
	colord_update_output_from_device (ocms);
out:
	g_hash_table_unref (device_props);
	if (device)
		g_object_unref (device);
	g_free (device_id);
}

static void
colord_notifier_output_created(struct wl_listener *listener, void *data)
{
	struct weston_output *o = (struct weston_output *) data;
	struct cms_colord *cms =
		container_of(listener, struct cms_colord, destroy_listener);
	weston_log("colord: output %s created\n", o->name);
	colord_output_created(cms, o);
}

static gpointer
colord_run_loop_thread(gpointer data)
{
	struct cms_colord *cms = (struct cms_colord *) data;
	struct weston_output *o;

	/* coldplug outputs */
	wl_list_for_each(o, &cms->ec->output_list, link) {
		weston_log("colord: output %s coldplugged\n", o->name);
		colord_output_created(cms, o);
	}

	g_main_loop_run(cms->loop);
	return NULL;
}

static int
colord_dispatch_all_pending(int fd, uint32_t mask, void *data)
{
	gchar tmp;
	GList *l;
	ssize_t rc;
	struct cms_colord *cms = data;
	struct cms_output *ocms;

	weston_log("colord: dispatching events\n");
	g_mutex_lock(&cms->pending_mutex);
	for (l = cms->pending; l != NULL; l = l->next) {
		ocms = l->data;

		/* optionally set backlight to calibration value */
		if (ocms->o->set_backlight && ocms->backlight_value != 0) {
			weston_log("colord: profile calibration backlight to %i/255\n",
				   ocms->backlight_value);
			ocms->o->set_backlight(ocms->o, ocms->backlight_value);
		}

		weston_cms_set_color_profile(ocms->o, ocms->p);
	}
	g_list_free (cms->pending);
	cms->pending = NULL;
	g_mutex_unlock(&cms->pending_mutex);

	/* done */
	rc = read(cms->readfd, &tmp, 1);
	if (rc == 0)
		weston_log("colord: failed to read from pending fd\n");
	return 1;
}

static void
colord_load_pnp_ids(struct cms_colord *cms)
{
	gboolean ret = FALSE;
	gchar *tmp;
	GError *error = NULL;
	guint i;
	const gchar *pnp_ids_fn[] = { "/usr/share/hwdata/pnp.ids",
				      "/usr/share/misc/pnp.ids",
				      NULL };

	/* find and load file */
	for (i = 0; pnp_ids_fn[i] != NULL; i++) {
		if (!g_file_test(pnp_ids_fn[i], G_FILE_TEST_EXISTS))
			continue;
		ret = g_file_get_contents(pnp_ids_fn[i],
					  &cms->pnp_ids_data,
					  NULL,
					  &error);
		if (!ret) {
			weston_log("colord: failed to load %s: %s\n",
				   pnp_ids_fn[i], error->message);
			g_error_free(error);
			return;
		}
		break;
	}
	if (!ret) {
		weston_log("colord: no pnp.ids found\n");
		return;
	}

	/* parse fixed offsets into lines */
	tmp = cms->pnp_ids_data;
	for (i = 0; cms->pnp_ids_data[i] != '\0'; i++) {
		if (cms->pnp_ids_data[i] != '\n')
			continue;
		cms->pnp_ids_data[i] = '\0';
		if (tmp[0] && tmp[1] && tmp[2] && tmp[3] == '\t' && tmp[4]) {
			tmp[3] = '\0';
			g_hash_table_insert(cms->pnp_ids, tmp, tmp+4);
			tmp = &cms->pnp_ids_data[i+1];
		}
	}
}

static void
colord_module_destroy(struct cms_colord *cms)
{
	if (cms->loop) {
		g_main_loop_quit(cms->loop);
		g_main_loop_unref(cms->loop);
	}
	if (cms->thread)
		g_thread_join(cms->thread);

	/* cms->devices must be destroyed before other resources, as
	 * the other resources are needed during output cleanup in
	 * cms->devices unref.
	 */
	if (cms->devices)
		g_hash_table_unref(cms->devices);
	if (cms->client)
		g_object_unref(cms->client);
	if (cms->readfd)
		close(cms->readfd);
	if (cms->writefd)
		close(cms->writefd);

	g_free(cms->pnp_ids_data);
	g_hash_table_unref(cms->pnp_ids);

	free(cms);
}

static void
colord_notifier_destroy(struct wl_listener *listener, void *data)
{
	struct cms_colord *cms =
		container_of(listener, struct cms_colord, destroy_listener);
	colord_module_destroy(cms);
}

static void
colord_cms_output_destroy(gpointer data)
{
	struct cms_output *ocms = (struct cms_output *) data;
	struct cms_colord *cms = ocms->cms;
	struct weston_output *o = ocms->o;
	gboolean ret;
	gchar *device_id;
	GError *error = NULL;

	colord_idle_cancel_for_output(cms, o);
	device_id = get_output_id(cms, o);
	weston_log("colord: output unplugged %s\n", device_id);

	wl_list_remove(&ocms->destroy_listener.link);
	g_signal_handlers_disconnect_by_data(ocms->device, ocms);

	ret = cd_client_delete_device_sync (cms->client,
					    ocms->device,
					    NULL,
					    &error);

	if (!ret) {
		weston_log("colord: failed to delete device: %s\n",
			   error->message);
		g_error_free(error);
	}

	g_object_unref(ocms->device);
	g_slice_free(struct cms_output, ocms);
	g_free (device_id);
}

WL_EXPORT int
wet_module_init(struct weston_compositor *ec,
		int *argc, char *argv[])
{
	gboolean ret;
	GError *error = NULL;
	int fd[2];
	struct cms_colord *cms;
	struct wl_event_loop *loop;

	weston_log("colord: initialized\n");

	/* create local state object */
	cms = zalloc(sizeof *cms);
	if (cms == NULL)
		return -1;
	cms->ec = ec;
#if !GLIB_CHECK_VERSION(2,36,0)
	g_type_init();
#endif
	cms->client = cd_client_new();
	ret = cd_client_connect_sync(cms->client, NULL, &error);
	if (!ret) {
		weston_log("colord: failed to contact daemon: %s\n", error->message);
		g_error_free(error);
		colord_module_destroy(cms);
		return -1;
	}
	g_mutex_init(&cms->pending_mutex);
	cms->devices = g_hash_table_new_full(g_str_hash, g_str_equal,
					     g_free, colord_cms_output_destroy);

	/* destroy */
	cms->destroy_listener.notify = colord_notifier_destroy;
	wl_signal_add(&ec->destroy_signal, &cms->destroy_listener);

	/* devices added */
	cms->output_created_listener.notify = colord_notifier_output_created;
	wl_signal_add(&ec->output_created_signal, &cms->output_created_listener);

	/* add all the PNP IDs */
	cms->pnp_ids = g_hash_table_new_full(g_str_hash,
					     g_str_equal,
					     NULL,
					     NULL);
	colord_load_pnp_ids(cms);

	/* setup a thread for the GLib callbacks */
	cms->loop = g_main_loop_new(NULL, FALSE);
	cms->thread = g_thread_new("colord CMS main loop",
				   colord_run_loop_thread, cms);

	/* batch device<->profile updates */
	if (pipe2(fd, O_CLOEXEC) == -1) {
		colord_module_destroy(cms);
		return -1;
	}
	cms->readfd = fd[0];
	cms->writefd = fd[1];
	loop = wl_display_get_event_loop(ec->wl_display);
	cms->source = wl_event_loop_add_fd (loop,
					    cms->readfd,
					    WL_EVENT_READABLE,
					    colord_dispatch_all_pending,
					    cms);
	if (!cms->source) {
		colord_module_destroy(cms);
		return -1;
	}
	return 0;
}
