/*
 *
 *  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 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);
}

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("network %s \"Unknown\" \"%s (Bluetooth)\"", uri, escaped);
	if (id != NULL)
		printf(" \"%s\"\n", id);
	else
		printf("\n");
	g_free(escaped);
	g_free(uri);
}

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;
	} else {
		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)
{
	GSList *l;

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

		if (device->name == NULL)
			device->name = g_strdelimit(g_strdup(device->bdaddr), ":", '-');
		/* Give another try to getting an ID for the device */
		if (device->id == NULL)
			remote_device_found(NULL, device->bdaddr, device->name);
		print_printer_details(device->name, device->bdaddr, device->id);
		g_free(device->name);
		g_free(device->bdaddr);
		g_free(device->id);
		g_free(device);
	}

	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);
		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 FALSE;

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

	if (!hcid_exists)
		return FALSE;

	/* 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);
		return FALSE;
	}

	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);

	/* 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;
}
