/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2003-2009  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <glib.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include <gdbus.h>

#include "cups.h"

struct cups_device {
	char *bdaddr;
	char *name;
	char *id;
};

static GSList *device_list = NULL;
static GMainLoop *loop = NULL;
static DBusConnection *conn = NULL;
static gboolean doing_disco = FALSE;

#define ATTRID_1284ID 0x0300

struct context_data {
	gboolean found;
	char *id;
};

static void element_start(GMarkupParseContext *context,
		const gchar *element_name, const gchar **attribute_names,
		const gchar **attribute_values, gpointer user_data, GError **err)
{
	struct context_data *ctx_data = user_data;

	if (!strcmp(element_name, "record"))
		return;

	if (!strcmp(element_name, "attribute")) {
		int i;
		for (i = 0; attribute_names[i]; i++) {
			if (!strcmp(attribute_names[i], "id")) {
				if (strtol(attribute_values[i], 0, 0) == ATTRID_1284ID)
					ctx_data->found = TRUE;
				break;
			}
		}
		return;
	}

	if (ctx_data->found  && !strcmp(element_name, "text")) {
		int i;
		for (i = 0; attribute_names[i]; i++) {
			if (!strcmp(attribute_names[i], "value")) {
				ctx_data->id = g_strdup(attribute_values[i] + 2);
				ctx_data->found = FALSE;
			}
		}
	}
}

static GMarkupParser parser = {
	element_start, NULL, NULL, NULL, NULL
};

static char *sdp_xml_parse_record(const char *data)
{
	GMarkupParseContext *ctx;
	struct context_data ctx_data;
	int size;

	size = strlen(data);
	ctx_data.found = FALSE;
	ctx_data.id = NULL;
	ctx = g_markup_parse_context_new(&parser, 0, &ctx_data, NULL);

	if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) {
		g_markup_parse_context_free(ctx);
		g_free(ctx_data.id);
		return NULL;
	}

	g_markup_parse_context_free(ctx);

	return ctx_data.id;
}

static char *device_get_ieee1284_id(const char *adapter, const char *device)
{
	DBusMessage *message, *reply;
	DBusMessageIter iter, reply_iter;
	DBusMessageIter reply_iter_entry;
	const char *hcr_print = "00001126-0000-1000-8000-00805f9b34fb";
	const char *xml;
	char *id = NULL;

	/* Look for the service handle of the HCRP service */
	message = dbus_message_new_method_call("org.bluez", device,
						"org.bluez.Device",
						"DiscoverServices");
	dbus_message_iter_init_append(message, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &hcr_print);

	reply = dbus_connection_send_with_reply_and_block(conn,
							message, -1, NULL);

	dbus_message_unref(message);

	if (!reply)
		return NULL;

	dbus_message_iter_init(reply, &reply_iter);

	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
		dbus_message_unref(reply);
		return NULL;
	}

	dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);

	/* Hopefully we only get one handle, or take a punt */
	while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) {
		guint32 key;
		DBusMessageIter dict_entry;

		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);

		/* Key ? */
		dbus_message_iter_get_basic(&dict_entry, &key);
		if (!key) {
			dbus_message_iter_next(&reply_iter_entry);
			continue;
		}

		/* Try to get the value */
		if (!dbus_message_iter_next(&dict_entry)) {
			dbus_message_iter_next(&reply_iter_entry);
			continue;
		}

		dbus_message_iter_get_basic(&dict_entry, &xml);

		id = sdp_xml_parse_record(xml);
		if (id != NULL)
			break;
		dbus_message_iter_next(&reply_iter_entry);
	}

	dbus_message_unref(reply);

	return id;
}

static void print_printer_details(const char *name, const char *bdaddr, const char *id)
{
	char *uri, *escaped;

	escaped = g_strdelimit(g_strdup(name), "\"", '\'');
	uri = g_strdup_printf("bluetooth://%c%c%c%c%c%c%c%c%c%c%c%c",
		 bdaddr[0], bdaddr[1],
		 bdaddr[3], bdaddr[4],
		 bdaddr[6], bdaddr[7],
		 bdaddr[9], bdaddr[10],
		 bdaddr[12], bdaddr[13],
		 bdaddr[15], bdaddr[16]);
	printf("direct %s \"%s\" \"%s (Bluetooth)\"", uri, escaped, escaped);
	if (id != NULL)
		printf(" \"%s\"\n", id);
	else
		printf("\n");
	g_free(escaped);
	g_free(uri);
}

static void add_device_to_list(const char *name, const char *bdaddr, const char *id)
{
	struct cups_device *device;
	GSList *l;

	/* Look for the device in the list */
	for (l = device_list; l != NULL; l = l->next) {
		device = (struct cups_device *) l->data;

		if (strcmp(device->bdaddr, bdaddr) == 0) {
			if (device->name != name) {
				g_free(device->name);
				device->name = g_strdup(name);
			}
			g_free(device->id);
			device->id = g_strdup(id);
			return;
		}
	}

	/* Or add it to the list if it's not there */
	device = g_new0(struct cups_device, 1);
	device->bdaddr = g_strdup(bdaddr);
	device->name = g_strdup(name);
	device->id = g_strdup(id);

	device_list = g_slist_prepend(device_list, device);
	print_printer_details(device->name, device->bdaddr, device->id);
}

static gboolean parse_device_properties(DBusMessageIter *reply_iter, char **name, char **bdaddr)
{
	guint32 class = 0;
	DBusMessageIter reply_iter_entry;

	if (dbus_message_iter_get_arg_type(reply_iter) != DBUS_TYPE_ARRAY)
		return FALSE;

	dbus_message_iter_recurse(reply_iter, &reply_iter_entry);

	while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) {
		const char *key;
		DBusMessageIter dict_entry, iter_dict_val;

		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);

		/* Key == Class ? */
		dbus_message_iter_get_basic(&dict_entry, &key);
		if (!key) {
			dbus_message_iter_next(&reply_iter_entry);
			continue;
		}

		if (strcmp(key, "Class") != 0 &&
				strcmp(key, "Alias") != 0 &&
				strcmp(key, "Address") != 0) {
			dbus_message_iter_next(&reply_iter_entry);
			continue;
		}

		/* Try to get the value */
		if (!dbus_message_iter_next(&dict_entry)) {
			dbus_message_iter_next(&reply_iter_entry);
			continue;
		}
		dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
		if (strcmp(key, "Class") == 0) {
			dbus_message_iter_get_basic(&iter_dict_val, &class);
		} else {
			const char *value;
			dbus_message_iter_get_basic(&iter_dict_val, &value);
			if (strcmp(key, "Alias") == 0) {
				*name = g_strdup(value);
			} else if (bdaddr) {
				*bdaddr = g_strdup(value);
			}
		}
		dbus_message_iter_next(&reply_iter_entry);
	}

	if (class == 0)
		return FALSE;
	if (((class & 0x1f00) >> 8) == 0x06 && (class & 0x80))
		return TRUE;

	return FALSE;
}

static gboolean device_is_printer(const char *adapter, const char *device_path, char **name, char **bdaddr)
{
	DBusMessage *message, *reply;
	DBusMessageIter reply_iter;
	gboolean retval;

	message = dbus_message_new_method_call("org.bluez", device_path,
					       "org.bluez.Device",
					       "GetProperties");

	reply = dbus_connection_send_with_reply_and_block(conn,
							message, -1, NULL);

	dbus_message_unref(message);

	if (!reply)
		return FALSE;

	dbus_message_iter_init(reply, &reply_iter);

	retval = parse_device_properties(&reply_iter, name, bdaddr);

	dbus_message_unref(reply);

	return retval;
}

static void remote_device_found(const char *adapter, const char *bdaddr, const char *name)
{
	DBusMessage *message, *reply, *adapter_reply;
	DBusMessageIter iter;
	char *object_path = NULL;
	char *id;

	adapter_reply = NULL;

	if (adapter == NULL) {
		message = dbus_message_new_method_call("org.bluez", "/",
						       "org.bluez.Manager",
						       "DefaultAdapter");

		adapter_reply = dbus_connection_send_with_reply_and_block(conn,
								  message, -1, NULL);

		dbus_message_unref(message);

		if (dbus_message_get_args(adapter_reply, NULL, DBUS_TYPE_OBJECT_PATH, &adapter, DBUS_TYPE_INVALID) == FALSE)
			return;
	}

	message = dbus_message_new_method_call("org.bluez", adapter,
					       "org.bluez.Adapter",
					       "FindDevice");
	dbus_message_iter_init_append(message, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);

	if (adapter_reply != NULL)
		dbus_message_unref(adapter_reply);

	reply = dbus_connection_send_with_reply_and_block(conn,
							message, -1, NULL);

	dbus_message_unref(message);

	if (!reply) {
		message = dbus_message_new_method_call("org.bluez", adapter,
						       "org.bluez.Adapter",
						       "CreateDevice");
		dbus_message_iter_init_append(message, &iter);
		dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);

		reply = dbus_connection_send_with_reply_and_block(conn,
								  message, -1, NULL);

		dbus_message_unref(message);

		if (!reply)
			return;
	}
	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &object_path,
				  DBUS_TYPE_INVALID) == FALSE) {
		return;
	}

	id = device_get_ieee1284_id(adapter, object_path);
	add_device_to_list(name, bdaddr, id);
	g_free(id);
}

static void discovery_completed(void)
{
	g_slist_free(device_list);
	device_list = NULL;

	g_main_loop_quit(loop);
}

static void remote_device_disappeared(const char *bdaddr)
{
	GSList *l;

	for (l = device_list; l != NULL; l = l->next) {
		struct cups_device *device = (struct cups_device *) l->data;

		if (strcmp(device->bdaddr, bdaddr) == 0) {
			g_free(device->name);
			g_free(device->bdaddr);
			g_free(device);
			device_list = g_slist_delete_link(device_list, l);
			return;
		}
	}
}

static gboolean list_known_printers(const char *adapter)
{
	DBusMessageIter reply_iter, iter_array;
	DBusError error;
	DBusMessage *message, *reply;

	message = dbus_message_new_method_call ("org.bluez", adapter,
						"org.bluez.Adapter",
						"ListDevices");
	if (message == NULL)
		return FALSE;

	dbus_error_init(&error);
	reply = dbus_connection_send_with_reply_and_block(conn,
							message, -1, &error);

	dbus_message_unref(message);

	if (&error != NULL && dbus_error_is_set(&error))
		return FALSE;

	dbus_message_iter_init(reply, &reply_iter);
	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
		dbus_message_unref(reply);
		return FALSE;
	}

	dbus_message_iter_recurse(&reply_iter, &iter_array);
	while (dbus_message_iter_get_arg_type(&iter_array) == DBUS_TYPE_OBJECT_PATH) {
		const char *object_path;
		char *name = NULL;
		char *bdaddr = NULL;

		dbus_message_iter_get_basic(&iter_array, &object_path);
		if (device_is_printer(adapter, object_path, &name, &bdaddr)) {
			char *id;

			id = device_get_ieee1284_id(adapter, object_path);
			add_device_to_list(name, bdaddr, id);
			g_free(id);
		}
		g_free(name);
		g_free(bdaddr);
		dbus_message_iter_next(&iter_array);
	}

	dbus_message_unref(reply);

	return FALSE;
}

static DBusHandlerResult filter_func(DBusConnection *connection, DBusMessage *message, void *user_data)
{
	if (dbus_message_is_signal(message, "org.bluez.Adapter",
						"DeviceFound")) {
		const char *adapter, *bdaddr;
		char *name;
		DBusMessageIter iter;

		dbus_message_iter_init(message, &iter);
		dbus_message_iter_get_basic(&iter, &bdaddr);
		dbus_message_iter_next(&iter);

		adapter = dbus_message_get_path(message);
		if (parse_device_properties(&iter, &name, NULL))
			remote_device_found(adapter, bdaddr, name);
		g_free (name);
	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
						"DeviceDisappeared")) {
		char *bdaddr;

		dbus_message_get_args(message, NULL,
					DBUS_TYPE_STRING, &bdaddr,
					DBUS_TYPE_INVALID);
		remote_device_disappeared(bdaddr);
	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
						"PropertyChanged")) {
		DBusMessageIter iter, value_iter;
		const char *name;
		gboolean discovering;

		dbus_message_iter_init(message, &iter);
		dbus_message_iter_get_basic(&iter, &name);
		if (name == NULL || strcmp(name, "Discovering") != 0)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		dbus_message_iter_next(&iter);
		dbus_message_iter_recurse(&iter, &value_iter);
		dbus_message_iter_get_basic(&value_iter, &discovering);

		if (discovering == FALSE && doing_disco) {
			doing_disco = FALSE;
			discovery_completed();
		}
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static gboolean list_printers(void)
{
	/* 1. Connect to the bus
	 * 2. Get the manager
	 * 3. Get the default adapter
	 * 4. Get a list of devices
	 * 5. Get the class of each device
	 * 6. Print the details from each printer device
	 */
	DBusError error;
	dbus_bool_t hcid_exists;
	DBusMessage *reply, *message;
	DBusMessageIter reply_iter;
	char *adapter, *match;

	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
	if (conn == NULL)
		return TRUE;

	dbus_error_init(&error);
	hcid_exists = dbus_bus_name_has_owner(conn, "org.bluez", &error);
	if (&error != NULL && dbus_error_is_set(&error))
		return TRUE;

	if (!hcid_exists)
		return TRUE;

	/* Get the default adapter */
	message = dbus_message_new_method_call("org.bluez", "/",
						"org.bluez.Manager",
						"DefaultAdapter");
	if (message == NULL) {
		dbus_connection_unref(conn);
		return FALSE;
	}

	reply = dbus_connection_send_with_reply_and_block(conn,
							message, -1, &error);

	dbus_message_unref(message);

	if (&error != NULL && dbus_error_is_set(&error)) {
		dbus_connection_unref(conn);
		/* No adapter */
		return TRUE;
	}

	dbus_message_iter_init(reply, &reply_iter);
	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_OBJECT_PATH) {
		dbus_message_unref(reply);
		dbus_connection_unref(conn);
		return FALSE;
	}

	dbus_message_iter_get_basic(&reply_iter, &adapter);
	adapter = g_strdup(adapter);
	dbus_message_unref(reply);

	if (!dbus_connection_add_filter(conn, filter_func, adapter, g_free)) {
		g_free(adapter);
		dbus_connection_unref(conn);
		return FALSE;
	}

#define MATCH_FORMAT				\
	"type='signal',"			\
	"interface='org.bluez.Adapter',"	\
	"sender='org.bluez',"			\
	"path='%s'"

	match = g_strdup_printf(MATCH_FORMAT, adapter);
	dbus_bus_add_match(conn, match, &error);
	g_free(match);

	/* Add the the recent devices */
	list_known_printers(adapter);

	doing_disco = TRUE;
	message = dbus_message_new_method_call("org.bluez", adapter,
					"org.bluez.Adapter",
					"StartDiscovery");

	if (!dbus_connection_send_with_reply(conn, message, NULL, -1)) {
		dbus_message_unref(message);
		dbus_connection_unref(conn);
		g_free(adapter);
		return FALSE;
	}
	dbus_message_unref(message);

	loop = g_main_loop_new(NULL, TRUE);
	g_main_loop_run(loop);

	dbus_connection_unref(conn);

	return TRUE;
}

/*
 *  Usage: printer-uri job-id user title copies options [file]
 *
 */

int main(int argc, char *argv[])
{
	sdp_session_t *sdp;
	bdaddr_t bdaddr;
	unsigned short ctrl_psm, data_psm;
	uint8_t channel, b[6];
	char *ptr, str[3], device[18], service[12];
	const char *uri, *cups_class;
	int i, err, fd, copies, proto;

	/* Make sure status messages are not buffered */
	setbuf(stderr, NULL);

	/* Make sure output is not buffered */
	setbuf(stdout, NULL);

	/* Ignore SIGPIPE signals */
#ifdef HAVE_SIGSET
	sigset(SIGPIPE, SIG_IGN);
#elif defined(HAVE_SIGACTION)
	memset(&action, 0, sizeof(action));
	action.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &action, NULL);
#else
	signal(SIGPIPE, SIG_IGN);
#endif /* HAVE_SIGSET */

	if (argc == 1) {
		if (list_printers() == TRUE)
			return CUPS_BACKEND_OK;
		else
			return CUPS_BACKEND_FAILED;
	}

	if (argc < 6 || argc > 7) {
		fprintf(stderr, "Usage: bluetooth job-id user title copies options [file]\n");
		return CUPS_BACKEND_FAILED;
	}

	if (argc == 6) {
		fd = 0;
		copies = 1;
	} else {
		if ((fd = open(argv[6], O_RDONLY)) < 0) {
			perror("ERROR: Unable to open print file");
			return CUPS_BACKEND_FAILED;
		}
		copies = atoi(argv[4]);
	}

	uri = getenv("DEVICE_URI");
	if (!uri)
		uri = argv[0];

	if (strncasecmp(uri, "bluetooth://", 12)) {
		fprintf(stderr, "ERROR: No device URI found\n");
		return CUPS_BACKEND_FAILED;
	}

	ptr = argv[0] + 12;
	for (i = 0; i < 6; i++) {
		strncpy(str, ptr, 2);
		b[i] = (uint8_t) strtol(str, NULL, 16);
		ptr += 2;
	}
	sprintf(device, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
		b[0], b[1], b[2], b[3], b[4], b[5]);

	str2ba(device, &bdaddr);

	ptr = strchr(ptr, '/');
	if (ptr) {
		strncpy(service, ptr + 1, 12);

		if (!strncasecmp(ptr + 1, "spp", 3))
			proto = 1;
		else if (!strncasecmp(ptr + 1, "hcrp", 4))
			proto = 2;
		else
			proto = 0;
	} else {
		strcpy(service, "auto");
		proto = 0;
	}

	cups_class = getenv("CLASS");

	fprintf(stderr, "DEBUG: %s device %s service %s fd %d copies %d class %s\n",
			argv[0], device, service, fd, copies,
					cups_class ? cups_class : "(none)");

	fputs("STATE: +connecting-to-device\n", stderr);

service_search:
	sdp = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY);
	if (!sdp) {
		fprintf(stderr, "ERROR: Can't open Bluetooth connection\n");
		return CUPS_BACKEND_FAILED;
	}

	switch (proto) {
	case 1:
		err = sdp_search_spp(sdp, &channel);
		break;
	case 2:
		err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm);
		break;
	default:
		proto = 2;
		err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm);
		if (err) {
			proto = 1;
			err = sdp_search_spp(sdp, &channel);
		}
		break;
	}

	sdp_close(sdp);

	if (err) {
		if (cups_class) {
			fputs("INFO: Unable to contact printer, queuing on "
					"next printer in class...\n", stderr);
			sleep(5);
			return CUPS_BACKEND_FAILED;
		}
		sleep(20);
		fprintf(stderr, "ERROR: Can't get service information\n");
		goto service_search;
	}

connect:
	switch (proto) {
	case 1:
		err = spp_print(BDADDR_ANY, &bdaddr, channel,
						fd, copies, cups_class);
		break;
	case 2:
		err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm,
						fd, copies, cups_class);
		break;
	default:
		err = CUPS_BACKEND_FAILED;
		fprintf(stderr, "ERROR: Unsupported protocol\n");
		break;
	}

	if (err == CUPS_BACKEND_FAILED && cups_class) {
		fputs("INFO: Unable to contact printer, queuing on "
					"next printer in class...\n", stderr);
		sleep(5);
		return CUPS_BACKEND_FAILED;
	} else if (err == CUPS_BACKEND_RETRY) {
		sleep(20);
		goto connect;
	}

	if (fd != 0)
		close(fd);

	if (!err)
		fprintf(stderr, "INFO: Ready to print\n");

	return err;
}
