/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2011-2012  Intel Corporation. All rights reserved.
 *  Copyright (C) 2013-2014  BMW Car IT GmbH.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1 as published by the Free Software Foundation.
 *
 *  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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser 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
 *
 */

/*
 * This file is a copy from ELL which has been ported to use GLib's
 * data structures.
 */

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

#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>

#include <gdbus.h>

#include "src/shared/util.h"
#include "src/shared/netlink.h"

#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif

struct command {
	unsigned int id;
	uint32_t seq;
	uint32_t len;
	netlink_command_func_t handler;
	netlink_destroy_func_t destroy;
	void *user_data;
};

struct notify {
	uint32_t group;
	netlink_notify_func_t handler;
	netlink_destroy_func_t destroy;
	void *user_data;
};

struct netlink_info {
	uint32_t pid;
	GIOChannel *channel;
	uint32_t next_seq;
	GQueue *command_queue;
	GHashTable *command_pending;
	GHashTable *command_lookup;
	unsigned int next_command_id;
	GHashTable *notify_groups;
	GHashTable *notify_lookup;
	unsigned int next_notify_id;
	netlink_debug_func_t debug_handler;
	netlink_destroy_func_t debug_destroy;
	void *debug_data;
};


static void destroy_command(struct command *command)
{
	if (command->destroy)
		command->destroy(command->user_data);

	g_free(command);
}

static void destroy_notify(struct notify *notify)
{
	if (notify->destroy)
		notify->destroy(notify->user_data);

	g_free(notify);
}

static gboolean can_write_data(GIOChannel *chan,
				GIOCondition cond, gpointer user_data)
{
	struct netlink_info *netlink = user_data;
	struct command *command;
	struct sockaddr_nl addr;
	const void *data;
	ssize_t written;
	int sk;

	command = g_queue_pop_head(netlink->command_queue);
	if (!command)
		return FALSE;

	sk = g_io_channel_unix_get_fd(chan);

	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	addr.nl_pid = 0;

	data = ((void *) command) + NLMSG_ALIGN(sizeof(struct command));

	written = sendto(sk, data, command->len, 0,
				(struct sockaddr *) &addr, sizeof(addr));
	if (written < 0 || (uint32_t) written != command->len) {
		g_hash_table_remove(netlink->command_lookup,
					GUINT_TO_POINTER(command->id));
		destroy_command(command);
		return FALSE;
	}

	util_hexdump('<', data, command->len,
				netlink->debug_handler, netlink->debug_data);

	g_hash_table_replace(netlink->command_pending,
				GUINT_TO_POINTER(command->seq), command);

	return g_queue_get_length(netlink->command_queue) > 0;
}

static void do_notify(gpointer key, gpointer value, gpointer user_data)
{
	struct nlmsghdr *nlmsg = user_data;
	struct notify *notify = value;

	if (notify->handler) {
		notify->handler(nlmsg->nlmsg_type, NLMSG_DATA(nlmsg),
			nlmsg->nlmsg_len - NLMSG_HDRLEN, notify->user_data);
	}
}

static void process_broadcast(struct netlink_info *netlink, uint32_t group,
						struct nlmsghdr *nlmsg)
{
	GHashTable *notify_list;

	notify_list = g_hash_table_lookup(netlink->notify_groups,
					       GUINT_TO_POINTER(group));
	if (!notify_list)
		return;

	g_hash_table_foreach(notify_list, do_notify, nlmsg);
}

static void process_message(struct netlink_info *netlink,
				struct nlmsghdr *nlmsg)
{
	const void *data = nlmsg;
	struct command *command;

	command = g_hash_table_lookup(netlink->command_pending,
					GUINT_TO_POINTER(nlmsg->nlmsg_seq));
	if (!command)
		return;

	g_hash_table_remove(netlink->command_pending,
					GUINT_TO_POINTER(nlmsg->nlmsg_seq));

	if (!command->handler)
		goto done;

	if (nlmsg->nlmsg_type < NLMSG_MIN_TYPE) {
		const struct nlmsgerr *err;

		switch (nlmsg->nlmsg_type) {
		case NLMSG_ERROR:
			err = data + NLMSG_HDRLEN;

			command->handler(-err->error, 0, NULL, 0,
							command->user_data);
			break;
		}
	} else {
		command->handler(0, nlmsg->nlmsg_type, data + NLMSG_HDRLEN,
					nlmsg->nlmsg_len - NLMSG_HDRLEN,
					command->user_data);
	}

done:
	g_hash_table_remove(netlink->command_lookup,
				GUINT_TO_POINTER(command->id));

	destroy_command(command);
}

static void process_multi(struct netlink_info *netlink, struct nlmsghdr *nlmsg)
{
	const void *data = nlmsg;
	struct command *command;

	command = g_hash_table_lookup(netlink->command_pending,
					GUINT_TO_POINTER(nlmsg->nlmsg_seq));
	if (!command)
		return;

	if (!command->handler)
		goto done;

	if (nlmsg->nlmsg_type < NLMSG_MIN_TYPE) {
		const struct nlmsgerr *err;

		switch (nlmsg->nlmsg_type) {
		case NLMSG_DONE:
		case NLMSG_ERROR:
			err = data + NLMSG_HDRLEN;

			command->handler(-err->error, 0, NULL, 0,
							command->user_data);
			break;
		}
	} else {
		command->handler(0, nlmsg->nlmsg_type, data + NLMSG_HDRLEN,
					nlmsg->nlmsg_len - NLMSG_HDRLEN,
					command->user_data);
		return;
	}

done:
	g_hash_table_remove(netlink->command_pending,
			GUINT_TO_POINTER(nlmsg->nlmsg_seq));

	g_hash_table_remove(netlink->command_lookup,
			GUINT_TO_POINTER(command->id));

	destroy_command(command);
}

static gboolean can_read_data(GIOChannel *chan,
				GIOCondition cond, gpointer data)
{
	struct netlink_info *netlink = data;
	struct cmsghdr *cmsg;
	struct msghdr msg;
	struct iovec iov;
	struct nlmsghdr *nlmsg;
	unsigned char buffer[4096];
	unsigned char control[32];
	uint32_t group = 0;
	ssize_t len;
	int sk;

	sk = g_io_channel_unix_get_fd(chan);

	iov.iov_base = buffer;
	iov.iov_len = sizeof(buffer);

	memset(&msg, 0, sizeof(msg));
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = control;
	msg.msg_controllen = sizeof(control);

	len = recvmsg(sk, &msg, 0);
	if (len < 0)
		return FALSE;

	util_hexdump('>', buffer, len, netlink->debug_handler,
			netlink->debug_data);

	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
					cmsg = CMSG_NXTHDR(&msg, cmsg)) {
		struct nl_pktinfo *pktinfo;

		if (cmsg->cmsg_level != SOL_NETLINK)
			continue;

		if (cmsg->cmsg_type != NETLINK_PKTINFO)
			continue;

		pktinfo = (void *) CMSG_DATA(cmsg);

		group = pktinfo->group;
	}

	for (nlmsg = iov.iov_base; NLMSG_OK(nlmsg, (uint32_t) len);
					nlmsg = NLMSG_NEXT(nlmsg, len)) {
		if (group > 0 && nlmsg->nlmsg_seq == 0) {
			process_broadcast(netlink, group, nlmsg);
			continue;
		}

		if (nlmsg->nlmsg_pid != netlink->pid)
			continue;

		if (nlmsg->nlmsg_flags & NLM_F_MULTI)
			process_multi(netlink, nlmsg);
		else
			process_message(netlink, nlmsg);
	}

	return TRUE;
}

static gboolean netlink_event(GIOChannel *chan,
				GIOCondition cond, gpointer data)
{
	if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
		return FALSE;

	return TRUE;
}

static int create_netlink_socket(int protocol, uint32_t *pid)
{
	struct sockaddr_nl addr;
	socklen_t addrlen = sizeof(addr);
	int sk, pktinfo = 1;

	sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
								protocol);
	if (sk < 0)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		close(sk);
		return -1;
	}

	if (getsockname(sk, (struct sockaddr *) &addr, &addrlen) < 0) {
		close(sk);
		return -1;
	}

	if (setsockopt(sk, SOL_NETLINK, NETLINK_PKTINFO,
					&pktinfo, sizeof(pktinfo)) < 0) {
		close(sk);
		return -1;
	}

	if (pid)
		*pid = addr.nl_pid;

	return sk;
}

struct netlink_info *netlink_new(int protocol)
{
	struct netlink_info *netlink;
	int sk;

	netlink = g_try_new0(struct netlink_info, 1);
	if (!netlink)
		return NULL;

	netlink->next_seq = 1;
	netlink->next_command_id = 1;
	netlink->next_notify_id = 1;

	sk = create_netlink_socket(protocol, &netlink->pid);
	if (sk < 0) {
		g_free(netlink);
		return NULL;
	}

	netlink->channel = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(netlink->channel, TRUE);

	g_io_channel_set_encoding(netlink->channel, NULL, NULL);
	g_io_channel_set_buffered(netlink->channel, FALSE);

	g_io_add_watch(netlink->channel, G_IO_IN, can_read_data, netlink);
	g_io_add_watch(netlink->channel, G_IO_NVAL | G_IO_HUP | G_IO_ERR,
			netlink_event, netlink);

	netlink->command_queue = g_queue_new();
	netlink->command_pending = g_hash_table_new(g_direct_hash,
							g_direct_equal);
	netlink->command_lookup = g_hash_table_new(g_direct_hash,
							g_direct_equal);

	netlink->notify_groups = g_hash_table_new(g_direct_hash,
							g_direct_equal);
	netlink->notify_lookup = g_hash_table_new(g_direct_hash,
							g_direct_equal);

	return netlink;
}

static gboolean cleanup_notify(gpointer key, gpointer value, gpointer user_data)
{
	struct notify *notify = value;

	destroy_notify(notify);

	return TRUE;

}

static gboolean cleanup_notify_group(gpointer key, gpointer value,
					gpointer user_data)
{
	GHashTable *notify_list = value;

	g_hash_table_foreach_remove(notify_list, cleanup_notify, user_data);
	g_hash_table_destroy(notify_list);

	return TRUE;
}

static gboolean cleanup_command(gpointer key, gpointer value,
					gpointer user_data)
{
	struct command *command = value;

	destroy_command(command);

	return TRUE;
}

void netlink_destroy(struct netlink_info *netlink)
{
	g_hash_table_destroy(netlink->notify_lookup);

	g_hash_table_foreach_remove(netlink->notify_groups,
				cleanup_notify_group, NULL);
	g_hash_table_destroy(netlink->notify_groups);

	g_queue_free(netlink->command_queue);

	g_hash_table_destroy(netlink->command_pending);

	g_hash_table_foreach_remove(netlink->command_lookup,
				cleanup_command, NULL);
	g_hash_table_destroy(netlink->command_lookup);

	g_io_channel_shutdown(netlink->channel, TRUE, NULL);
	g_io_channel_unref(netlink->channel);

	g_free(netlink);
}

unsigned int netlink_send(struct netlink_info *netlink,
			uint16_t type, uint16_t flags, const void *data,
			uint32_t len, netlink_command_func_t function,
			void *user_data, netlink_destroy_func_t destroy)
{
	struct command *command;
	struct nlmsghdr *nlmsg;
	size_t size;

	if (!netlink)
		return 0;

	if (!netlink->command_queue ||
			!netlink->command_pending ||
			!netlink->command_lookup)
		return 0;

	size = NLMSG_ALIGN(sizeof(struct command)) +
					NLMSG_HDRLEN + NLMSG_ALIGN(len);

	command = g_try_malloc0(size);
	if (!command)
		return 0;

	command->handler = function;
	command->destroy = destroy;
	command->user_data = user_data;

	command->id = netlink->next_command_id;

	g_hash_table_replace(netlink->command_lookup,
				GUINT_TO_POINTER(command->id), command);

	command->seq = netlink->next_seq++;
	command->len = NLMSG_HDRLEN + NLMSG_ALIGN(len);

	nlmsg = ((void *) command) + NLMSG_ALIGN(sizeof(struct command));

	nlmsg->nlmsg_len = command->len;
	nlmsg->nlmsg_type = type;
	nlmsg->nlmsg_flags = NLM_F_REQUEST | flags;
	nlmsg->nlmsg_seq = command->seq;
	nlmsg->nlmsg_pid = netlink->pid;

	if (data && len > 0)
		memcpy(((void *) nlmsg) + NLMSG_HDRLEN, data, len);

	g_queue_push_tail(netlink->command_queue, command);

	netlink->next_command_id++;

	/* Arm IOChannel to call can_write_data in case it is not armed yet. */
	if (g_queue_get_length(netlink->command_queue) == 1)
		g_io_add_watch(netlink->channel, G_IO_OUT, can_write_data,
				netlink);

	return command->id;
}

bool netlink_cancel(struct netlink_info *netlink, unsigned int id)
{
	struct command *command;

	if (!netlink || id == 0)
		return false;

	if (!netlink->command_queue ||
			!netlink->command_pending ||
			!netlink->command_lookup)
		return false;

	command = g_hash_table_lookup(netlink->command_lookup,
					GUINT_TO_POINTER(id));
	if (!command)
		return false;

	g_hash_table_remove(netlink->command_lookup, GUINT_TO_POINTER(id));

	g_queue_remove(netlink->command_queue, command);

	g_hash_table_remove(netlink->command_pending, GUINT_TO_POINTER(command->seq));

	destroy_command(command);

	return true;
}

static bool add_membership(struct netlink_info *netlink, uint32_t group)
{
	int sk, value = group;

	sk = g_io_channel_unix_get_fd(netlink->channel);

	if (setsockopt(sk, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
						&value, sizeof(value)) < 0)
		return false;

	return true;
}

static bool drop_membership(struct netlink_info *netlink, uint32_t group)
{
	int sk, value = group;

	sk = g_io_channel_unix_get_fd(netlink->channel);

	if (setsockopt(sk, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
						&value, sizeof(value)) < 0)
		return false;

	return true;
}

unsigned int netlink_register(struct netlink_info *netlink,
			uint32_t group, netlink_notify_func_t function,
			void *user_data, netlink_destroy_func_t destroy)
{
	GHashTable *notify_list;
	struct notify *notify;
	unsigned int id;

	if (!netlink)
		return 0;

	if (!netlink->notify_groups || !netlink->notify_lookup)
		return 0;

	notify_list = g_hash_table_lookup(netlink->notify_groups,
						GUINT_TO_POINTER(group));
	if (!notify_list) {
		notify_list = g_hash_table_new(g_direct_hash, g_direct_equal);
		if (!notify_list)
			return 0;

		g_hash_table_replace(netlink->notify_groups,
					GUINT_TO_POINTER(group), notify_list);
	}

	notify = g_new(struct notify, 1);

	notify->group = group;
	notify->handler = function;
	notify->destroy = destroy;
	notify->user_data = user_data;

	id = netlink->next_notify_id;

	g_hash_table_replace(netlink->notify_lookup,
				GUINT_TO_POINTER(id), notify_list);
	g_hash_table_replace(notify_list, GUINT_TO_POINTER(id), notify);

	if (g_hash_table_size(notify_list) == 1) {
		if (add_membership(netlink, notify->group) == false)
			goto remove_notify;
	}

	netlink->next_notify_id++;

	return id;

remove_notify:
	g_hash_table_remove(notify_list, GUINT_TO_POINTER(id));
	g_hash_table_remove(netlink->notify_lookup, GUINT_TO_POINTER(id));
	g_free(notify);

	return 0;
}

bool netlink_unregister(struct netlink_info *netlink, unsigned int id)
{
	GHashTable *notify_list;
	struct notify *notify;

	if (!netlink || id == 0)
		return false;

	if (!netlink->notify_groups || !netlink->notify_lookup)
		return false;

	notify_list = g_hash_table_lookup(netlink->notify_lookup,
						GUINT_TO_POINTER(id));

	if (!notify_list)
		return false;

	g_hash_table_remove(netlink->notify_lookup, GUINT_TO_POINTER(id));

	notify = g_hash_table_lookup(notify_list, GUINT_TO_POINTER(id));
	if (!notify)
		return false;

	g_hash_table_remove(notify_list, GUINT_TO_POINTER(id));

	if (g_hash_table_size(notify_list) == 0)
		drop_membership(netlink, notify->group);

	destroy_notify(notify);

	return true;
}

bool netlink_set_debug(struct netlink_info *netlink,
			netlink_debug_func_t function,
			void *user_data, netlink_destroy_func_t destroy)
{
	if (!netlink)
		return false;

	if (netlink->debug_destroy)
		netlink->debug_destroy(netlink->debug_data);

	netlink->debug_handler = function;
	netlink->debug_destroy = destroy;
	netlink->debug_data = user_data;

	return true;
}
