/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011  Red Hat, Inc.
 *  Copyright (C) 2004-2010  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
 *
 *  Author: Bastien Nocera <hadess@hadess.net>
 *  Marcel Holtmann <marcel@holtmann.org> (for expand_name)
 *
 */

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

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <glib.h>
#include <bluetooth/bluetooth.h>

#include "plugin.h"
#include "hcid.h" /* For main_opts */
#include "adapter.h"
#include "manager.h"
#include "device.h" /* Needed for storage.h */
#include "storage.h"
#include "log.h"

#include <sys/inotify.h>
#define EVENT_SIZE  (sizeof (struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))

#define MACHINE_INFO_DIR "/etc/"
#define MACHINE_INFO_FILE "machine-info"

static GIOChannel *inotify = NULL;
static int watch_fd = -1;

/* This file is part of systemd's hostnamed functionality:
 * http://0pointer.de/public/systemd-man/machine-info.html
 * http://www.freedesktop.org/wiki/Software/systemd/hostnamed
 */
static char *read_pretty_host_name(void)
{
	char *contents, *ret;
	char **lines;
	guint i;

	if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE,
					&contents, NULL, NULL) == FALSE)
		return NULL;

	lines = g_strsplit_set(contents, "\r\n", 0);
	g_free(contents);

	if (lines == NULL)
		return NULL;

	ret = NULL;
	for (i = 0; lines[i] != NULL; i++) {
		if (g_str_has_prefix(lines[i], "PRETTY_HOSTNAME=")) {
			ret = g_strdup(lines[i] + strlen("PRETTY_HOSTNAME="));
			break;
		}
	}

	g_strfreev(lines);

	return ret;
}

/*
 * Device name expansion
 *   %d - device id
 *   %h - hostname
 */
static char *expand_name(char *dst, int size, char *str, int dev_id)
{
	register int sp, np, olen;
	char *opt, buf[10];

	if (!str || !dst)
		return NULL;

	sp = np = 0;
	while (np < size - 1 && str[sp]) {
		switch (str[sp]) {
		case '%':
			opt = NULL;

			switch (str[sp+1]) {
			case 'd':
				sprintf(buf, "%d", dev_id);
				opt = buf;
				break;

			case 'h':
				opt = main_opts.host_name;
				break;

			case '%':
				dst[np++] = str[sp++];
				/* fall through */
			default:
				sp++;
				continue;
			}

			if (opt) {
				/* substitute */
				olen = strlen(opt);
				if (np + olen < size - 1)
					memcpy(dst + np, opt, olen);
				np += olen;
			}
			sp += 2;
			continue;

		case '\\':
			sp++;
			/* fall through */
		default:
			dst[np++] = str[sp++];
			break;
		}
	}
	dst[np] = '\0';
	return dst;
}

static int get_default_adapter_id(void)
{
	struct btd_adapter *default_adapter;

	default_adapter = manager_get_default_adapter();
	if (default_adapter == NULL)
		return -1;

	return adapter_get_dev_id(default_adapter);
}

static void set_pretty_name(struct btd_adapter *adapter,
						const char *pretty_hostname)
{
	int current_id;
	int default_adapter;

	default_adapter = get_default_adapter_id();
	current_id = adapter_get_dev_id(adapter);

	/* Allow us to change the name */
	adapter_set_allow_name_changes(adapter, TRUE);

	/* If it's the first device, let's assume it will be the
	 * default one, as we're not told when the default adapter
	 * changes */
	if (default_adapter < 0)
		default_adapter = current_id;

	if (default_adapter != current_id) {
		char *str;

		/* +1 because we don't want an adapter called "Foobar's
		 * laptop #0" */
		str = g_strdup_printf("%s #%d", pretty_hostname,
							current_id + 1);
		DBG("Setting name '%s' for device 'hci%d'", str, current_id);

		adapter_set_name(adapter, str);
		g_free(str);
	} else {
		DBG("Setting name '%s' for device 'hci%d'", pretty_hostname,
								current_id);
		adapter_set_name(adapter, pretty_hostname);
	}

	/* And disable the name change now */
	adapter_set_allow_name_changes(adapter, FALSE);
}

static int adaptername_probe(struct btd_adapter *adapter)
{
	int current_id;
	char name[MAX_NAME_LENGTH + 1];
	char *pretty_hostname;
	bdaddr_t bdaddr;

	pretty_hostname = read_pretty_host_name();
	if (pretty_hostname != NULL) {
		set_pretty_name(adapter, pretty_hostname);
		g_free(pretty_hostname);
		return 0;
	}

	adapter_set_allow_name_changes(adapter, TRUE);
	adapter_get_address(adapter, &bdaddr);
	current_id = adapter_get_dev_id(adapter);

	if (read_local_name(&bdaddr, name) < 0)
		expand_name(name, MAX_NAME_LENGTH, main_opts.name, current_id);

	DBG("Setting name '%s' for device 'hci%d'", name, current_id);
	adapter_set_name(adapter, name);

	return 0;
}

static gboolean handle_inotify_cb(GIOChannel *channel, GIOCondition cond,
								gpointer data)
{
	char buf[EVENT_BUF_LEN];
	GIOStatus err;
	gsize len, i;
	gboolean changed;

	changed = FALSE;

	err = g_io_channel_read_chars(channel, buf, EVENT_BUF_LEN, &len, NULL);
	if (err != G_IO_STATUS_NORMAL) {
		error("Error reading inotify event: %d\n", err);
		return FALSE;
	}

	i = 0;
	while (i < len) {
		struct inotify_event *pevent = (struct inotify_event *) &buf[i];

		/* check that it's ours */
		if (pevent->len && pevent->name != NULL &&
				strcmp(pevent->name, MACHINE_INFO_FILE) == 0)
			changed = TRUE;

		i += EVENT_SIZE + pevent->len;
	}

	if (changed != FALSE) {
		DBG(MACHINE_INFO_DIR MACHINE_INFO_FILE
				" changed, changing names for adapters");
		manager_foreach_adapter((adapter_cb) adaptername_probe, NULL);
	}

	return TRUE;
}

static void adaptername_remove(struct btd_adapter *adapter)
{
}

static struct btd_adapter_driver adaptername_driver = {
	.name	= "adaptername",
	.probe	= adaptername_probe,
	.remove	= adaptername_remove,
};

static int adaptername_init(void)
{
	int err;
	int inot_fd;
	guint32 mask;

	err = btd_register_adapter_driver(&adaptername_driver);
	if (err < 0)
		return err;

	inot_fd = inotify_init();
	if (inot_fd < 0) {
		error("Failed to setup inotify");
		return 0;
	}

	mask = IN_CLOSE_WRITE;
	mask |= IN_DELETE;
	mask |= IN_CREATE;
	mask |= IN_MOVED_FROM;
	mask |= IN_MOVED_TO;

	watch_fd = inotify_add_watch(inot_fd, MACHINE_INFO_DIR, mask);
	if (watch_fd < 0) {
		error("Failed to setup watch for '%s'", MACHINE_INFO_DIR);
		close(inot_fd);
		return 0;
	}

	inotify = g_io_channel_unix_new(inot_fd);
	g_io_channel_set_close_on_unref(inotify, TRUE);
	g_io_channel_set_encoding(inotify, NULL, NULL);
	g_io_channel_set_flags(inotify, G_IO_FLAG_NONBLOCK, NULL);
	g_io_add_watch(inotify, G_IO_IN, handle_inotify_cb, NULL);

	return 0;
}

static void adaptername_exit(void)
{
	if (watch_fd >= 0)
		close(watch_fd);
	if (inotify != NULL) {
		g_io_channel_shutdown(inotify, FALSE, NULL);
		g_io_channel_unref(inotify);
	}

	btd_unregister_adapter_driver(&adaptername_driver);
}

BLUETOOTH_PLUGIN_DEFINE(adaptername, VERSION,
		BLUETOOTH_PLUGIN_PRIORITY_LOW, adaptername_init, adaptername_exit)
