/*
 * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors:
 *
 * Simon Wunderlich
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License 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
 * 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 Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 *
 */

#include "main.h"
#include "send.h"
#include "translation-table.h"
#include "vis.h"
#include "log.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "hash.h"
#include "compat.h"

struct hashtable_t *vis_hash;
DEFINE_SPINLOCK(vis_hash_lock);
static struct vis_info *my_vis_info;
static struct list_head send_list;	/* always locked with vis_hash_lock */

static void start_vis_timer(void);

/* free the info */
static void free_info(void *data)
{
	struct vis_info *info = data;
	struct recvlist_node *entry, *tmp;

	list_del_init(&info->send_list);
	list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
		list_del(&entry->list);
		kfree(entry);
	}
	kfree(info);
}

/* set the mode of the visualization to client or server */
void vis_set_mode(int mode)
{
	spin_lock(&vis_hash_lock);

	if (my_vis_info != NULL)
		my_vis_info->packet.vis_type = mode;

	spin_unlock(&vis_hash_lock);
}

/* is_vis_server(), locked outside */
static int is_vis_server_locked(void)
{
	if (my_vis_info != NULL)
		if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
			return 1;

	return 0;
}

/* get the current set mode */
int is_vis_server(void)
{
	int ret = 0;

	spin_lock(&vis_hash_lock);
	ret = is_vis_server_locked();
	spin_unlock(&vis_hash_lock);

	return ret;
}

/* Compare two vis packets, used by the hashing algorithm */
static int vis_info_cmp(void *data1, void *data2)
{
	struct vis_info *d1, *d2;
	d1 = data1;
	d2 = data2;
	return compare_orig(d1->packet.vis_orig, d2->packet.vis_orig);
}

/* hash function to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
static int vis_info_choose(void *data, int size)
{
	struct vis_info *vis_info = data;
	unsigned char *key;
	uint32_t hash = 0;
	size_t i;

	key = vis_info->packet.vis_orig;
	for (i = 0; i < ETH_ALEN; i++) {
		hash += key[i];
		hash += (hash << 10);
		hash ^= (hash >> 6);
	}

	hash += (hash << 3);
	hash ^= (hash >> 11);
	hash += (hash << 15);

	return hash % size;
}

/* tries to add one entry to the receive list. */
static void recv_list_add(struct list_head *recv_list, char *mac)
{
	struct recvlist_node *entry;
	entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
	if (!entry)
		return;

	memcpy(entry->mac, mac, ETH_ALEN);
	list_add_tail(&entry->list, recv_list);
}

/* returns 1 if this mac is in the recv_list */
static int recv_list_is_in(struct list_head *recv_list, char *mac)
{
	struct recvlist_node *entry;

	list_for_each_entry(entry, recv_list, list) {
		if (memcmp(entry->mac, mac, ETH_ALEN) == 0)
			return 1;
	}

	return 0;
}

/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
 * broken.. ).  vis hash must be locked outside.  is_new is set when the packet
 * is newer than old entries in the hash. */
static struct vis_info *add_packet(struct vis_packet *vis_packet,
				   int vis_info_len, int *is_new)
{
	struct vis_info *info, *old_info;
	struct vis_info search_elem;

	*is_new = 0;
	/* sanity check */
	if (vis_hash == NULL)
		return NULL;

	/* see if the packet is already in vis_hash */
	memcpy(search_elem.packet.vis_orig, vis_packet->vis_orig, ETH_ALEN);
	old_info = hash_find(vis_hash, &search_elem);

	if (old_info != NULL) {
		if (vis_packet->seqno - old_info->packet.seqno <= 0) {
			if (old_info->packet.seqno == vis_packet->seqno) {
				recv_list_add(&old_info->recv_list,
					      vis_packet->sender_orig);
				return old_info;
			} else {
				/* newer packet is already in hash. */
				return NULL;
			}
		}
		/* remove old entry */
		hash_remove(vis_hash, old_info);
		free_info(old_info);
	}

	info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC);
	if (info == NULL)
		return NULL;

	INIT_LIST_HEAD(&info->send_list);
	INIT_LIST_HEAD(&info->recv_list);
	info->first_seen = jiffies;
	memcpy(&info->packet, vis_packet,
	       sizeof(struct vis_packet) + vis_info_len);

	/* initialize and add new packet. */
	*is_new = 1;

	/* repair if entries is longer than packet. */
	if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
		info->packet.entries = vis_info_len / sizeof(struct vis_info_entry);

	recv_list_add(&info->recv_list, info->packet.sender_orig);

	/* try to add it */
	if (hash_add(vis_hash, info) < 0) {
		/* did not work (for some reason) */
		free_info(info);
		info = NULL;
	}

	return info;
}

/* handle the server sync packet, forward if needed. */
void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
{
	struct vis_info *info;
	int is_new;

	spin_lock(&vis_hash_lock);
	info = add_packet(vis_packet, vis_info_len, &is_new);
	if (info == NULL)
		goto end;

	/* only if we are server ourselves and packet is newer than the one in
	 * hash.*/
	if (is_vis_server_locked() && is_new) {
		memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
		if (list_empty(&info->send_list))
			list_add_tail(&info->send_list, &send_list);
	}
end:
	spin_unlock(&vis_hash_lock);
}

/* handle an incoming client update packet and schedule forward if needed. */
void receive_client_update_packet(struct vis_packet *vis_packet,
				  int vis_info_len)
{
	struct vis_info *info;
	int is_new;

	/* clients shall not broadcast. */
	if (is_bcast(vis_packet->target_orig))
		return;

	spin_lock(&vis_hash_lock);
	info = add_packet(vis_packet, vis_info_len, &is_new);
	if (info == NULL)
		goto end;
	/* note that outdated packets will be dropped at this point. */


	/* send only if we're the target server or ... */
	if (is_vis_server_locked() &&
	    is_my_mac(info->packet.target_orig) &&
	    is_new) {
		info->packet.vis_type = VIS_TYPE_SERVER_SYNC;	/* upgrade! */
		memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
		if (list_empty(&info->send_list))
			list_add_tail(&info->send_list, &send_list);

		/* ... we're not the recipient (and thus need to forward). */
	} else if (!is_my_mac(info->packet.target_orig)) {
		if (list_empty(&info->send_list))
			list_add_tail(&info->send_list, &send_list);
	}
end:
	spin_unlock(&vis_hash_lock);
}

/* Walk the originators and find the VIS server with the best tq. Set the packet
 * address to its address and return the best_tq.
 *
 * Must be called with the originator hash locked */
static int find_best_vis_server(struct vis_info *info)
{
	struct hash_it_t *hashit = NULL;
	struct orig_node *orig_node;
	int best_tq = -1;

	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
		orig_node = hashit->bucket->data;
		if ((orig_node != NULL) &&
		    (orig_node->router != NULL) &&
		    (orig_node->flags & VIS_SERVER) &&
		    (orig_node->router->tq_avg > best_tq)) {
			best_tq = orig_node->router->tq_avg;
			memcpy(info->packet.target_orig, orig_node->orig,
			       ETH_ALEN);
		}
	}
	return best_tq;
}

/* Return true if the vis packet is full. */
static bool vis_packet_full(struct vis_info *info)
{
	if (info->packet.entries + 1 >
	    (1000 - sizeof(struct vis_info)) / sizeof(struct vis_info_entry))
		return true;
	return false;
}

/* generates a packet of own vis data,
 * returns 0 on success, -1 if no packet could be generated */
static int generate_vis_packet(void)
{
	struct hash_it_t *hashit = NULL;
	struct orig_node *orig_node;
	struct vis_info *info = (struct vis_info *)my_vis_info;
	struct vis_info_entry *entry, *entry_array;
	struct hna_local_entry *hna_local_entry;
	int best_tq = -1;
	unsigned long flags;

	info->first_seen = jiffies;

	spin_lock(&orig_hash_lock);
	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
	info->packet.ttl = TTL;
	info->packet.seqno++;
	info->packet.entries = 0;

	if (!is_vis_server_locked()) {
		best_tq = find_best_vis_server(info);
		if (best_tq < 0) {
			spin_unlock(&orig_hash_lock);
			return -1;
		}
	}
	hashit = NULL;

	entry_array = (struct vis_info_entry *)
		((char *)info + sizeof(struct vis_info));

	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
		orig_node = hashit->bucket->data;
		if (orig_node->router != NULL
			&& compare_orig(orig_node->router->addr, orig_node->orig)
			&& orig_node->batman_if
			&& (orig_node->batman_if->if_active == IF_ACTIVE)
		    && orig_node->router->tq_avg > 0) {

			/* fill one entry into buffer. */
			entry = &entry_array[info->packet.entries];
			memcpy(entry->src, orig_node->batman_if->net_dev->dev_addr, ETH_ALEN);
			memcpy(entry->dest, orig_node->orig, ETH_ALEN);
			entry->quality = orig_node->router->tq_avg;
			info->packet.entries++;

			if (vis_packet_full(info)) {
				spin_unlock(&orig_hash_lock);
				return 0;
			}
		}
	}

	spin_unlock(&orig_hash_lock);

	hashit = NULL;
	spin_lock_irqsave(&hna_local_hash_lock, flags);
	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
		hna_local_entry = hashit->bucket->data;
		entry = &entry_array[info->packet.entries];
		memset(entry->src, 0, ETH_ALEN);
		memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
		entry->quality = 0; /* 0 means HNA */
		info->packet.entries++;

		if (vis_packet_full(info)) {
			spin_unlock_irqrestore(&hna_local_hash_lock, flags);
			return 0;
		}
	}
	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
	return 0;
}

static void purge_vis_packets(void)
{
	struct hash_it_t *hashit = NULL;
	struct vis_info *info;

	while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
		info = hashit->bucket->data;
		if (info == my_vis_info)	/* never purge own data. */
			continue;
		if (time_after(jiffies,
			       info->first_seen + (VIS_TIMEOUT/1000)*HZ)) {
			hash_remove_bucket(vis_hash, hashit);
			free_info(info);
		}
	}
}

static void broadcast_vis_packet(struct vis_info *info, int packet_length)
{
	struct hash_it_t *hashit = NULL;
	struct orig_node *orig_node;

	spin_lock(&orig_hash_lock);

	/* send to all routers in range. */
	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
		orig_node = hashit->bucket->data;

		/* if it's a vis server and reachable, send it. */
		if (orig_node &&
		    (orig_node->flags & VIS_SERVER) &&
		    orig_node->batman_if &&
		    orig_node->router) {

			/* don't send it if we already received the packet from
			 * this node. */
			if (recv_list_is_in(&info->recv_list, orig_node->orig))
				continue;

			memcpy(info->packet.target_orig,
			       orig_node->orig, ETH_ALEN);

			send_raw_packet((unsigned char *) &info->packet,
					packet_length,
					orig_node->batman_if,
					orig_node->router->addr);
		}
	}
	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
	spin_unlock(&orig_hash_lock);
}

static void unicast_vis_packet(struct vis_info *info, int packet_length)
{
	struct orig_node *orig_node;

	spin_lock(&orig_hash_lock);
	orig_node = ((struct orig_node *)
		     hash_find(orig_hash, info->packet.target_orig));

	if ((orig_node != NULL) &&
	    (orig_node->batman_if != NULL) &&
	    (orig_node->router != NULL)) {
		send_raw_packet((unsigned char *) &info->packet, packet_length,
				orig_node->batman_if,
				orig_node->router->addr);
	}
	spin_unlock(&orig_hash_lock);
}

/* only send one vis packet. called from send_vis_packets() */
static void send_vis_packet(struct vis_info *info)
{
	int packet_length;

	if (info->packet.ttl < 2) {
		debug_log(LOG_TYPE_NOTICE,
			  "Error - can't send vis packet: ttl exceeded\n");
		return;
	}

	memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN);
	info->packet.ttl--;

	packet_length = sizeof(struct vis_packet) +
		info->packet.entries * sizeof(struct vis_info_entry);

	if (is_bcast(info->packet.target_orig))
		broadcast_vis_packet(info, packet_length);
	else
		unicast_vis_packet(info, packet_length);
	info->packet.ttl++; /* restore TTL */
}

/* called from timer; send (and maybe generate) vis packet. */
static void send_vis_packets(struct work_struct *work)
{
	struct vis_info *info, *temp;

	spin_lock(&vis_hash_lock);
	purge_vis_packets();

	if (generate_vis_packet() == 0)
		/* schedule if generation was successful */
		list_add_tail(&my_vis_info->send_list, &send_list);

	list_for_each_entry_safe(info, temp, &send_list, send_list) {
		list_del_init(&info->send_list);
		send_vis_packet(info);
	}
	spin_unlock(&vis_hash_lock);
	start_vis_timer();
}
static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);

/* init the vis server. this may only be called when if_list is already
 * initialized (e.g. bat0 is initialized, interfaces have been added) */
int vis_init(void)
{
	if (vis_hash)
		return 1;

	spin_lock(&vis_hash_lock);

	vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
	if (!vis_hash) {
		debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n");
		goto err;
	}

	my_vis_info = kmalloc(1000, GFP_ATOMIC);
	if (!my_vis_info) {
		debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n");
		goto err;
	}

	/* prefill the vis info */
	my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
	INIT_LIST_HEAD(&my_vis_info->recv_list);
	INIT_LIST_HEAD(&my_vis_info->send_list);
	my_vis_info->packet.version = COMPAT_VERSION;
	my_vis_info->packet.packet_type = BAT_VIS;
	my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
	my_vis_info->packet.ttl = TTL;
	my_vis_info->packet.seqno = 0;
	my_vis_info->packet.entries = 0;

	INIT_LIST_HEAD(&send_list);

	memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN);
	memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);

	if (hash_add(vis_hash, my_vis_info) < 0) {
		debug_log(LOG_TYPE_CRIT,
			  "Can't add own vis packet into hash\n");
		free_info(my_vis_info);	/* not in hash, need to remove it
					 * manually. */
		goto err;
	}

	spin_unlock(&vis_hash_lock);
	start_vis_timer();
	return 1;

err:
	spin_unlock(&vis_hash_lock);
	vis_quit();
	return 0;
}

/* shutdown vis-server */
void vis_quit(void)
{
	if (!vis_hash)
		return;

	cancel_delayed_work_sync(&vis_timer_wq);

	spin_lock(&vis_hash_lock);
	/* properly remove, kill timers ... */
	hash_delete(vis_hash, free_info);
	vis_hash = NULL;
	my_vis_info = NULL;
	spin_unlock(&vis_hash_lock);
}

/* schedule packets for (re)transmission */
static void start_vis_timer(void)
{
	queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
			   (atomic_read(&vis_interval)/1000) * HZ);
}

