#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/time.h>
#include <assert.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>


#include <ccn/ccn.h>
#include <ccn/uri.h>
#include <ccn/keystore.h>
#include <ccn/signing.h>
#include <ccn/schedule.h>
#include <ccn/hashtb.h>


#include "nlsr.h"
#include "nlsr_route.h"
#include "nlsr_lsdb.h"
#include "nlsr_npt.h"
#include "nlsr_adl.h"
#include "nlsr_fib.h"
#include "utility.h"

int
route_calculate(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags)
{

	if(flags == CCN_SCHEDULE_CANCEL)
	{
 	 	return -1;
	}

	nlsr_lock();

	if ( nlsr->debugging )
		printf("route_calculate called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"route_calculate called\n");

	if( ! nlsr->is_build_adj_lsa_sheduled )
	{
		/* Calculate Route here */
		print_routing_table();
		print_npt();		

		struct hashtb_param param_me = {0};
		nlsr->map = hashtb_create(sizeof(struct map_entry), &param_me);
		nlsr->rev_map = hashtb_create(sizeof(struct map_entry), &param_me);
		make_map();
		assign_mapping_number();		
		print_map();
		print_rev_map();

		do_old_routing_table_updates();
		clear_old_routing_table();	
		print_routing_table();
		print_npt();

		int i;
		int **adj_matrix;
		int map_element=hashtb_n(nlsr->map);
		adj_matrix=malloc(map_element * sizeof(int *));
		for(i = 0; i < map_element; i++)
		{
			adj_matrix[i] = malloc(map_element * sizeof(int));
		}
		make_adj_matrix(adj_matrix,map_element);
		if ( nlsr->debugging )
			print_adj_matrix(adj_matrix,map_element);

		long int source=get_mapping_no(nlsr->router_name);
		int num_link=get_no_link_from_adj_matrix(adj_matrix, map_element ,source);

		if ( nlsr->is_hyperbolic_calc == 1)
		{
			long int *links=(long int *)malloc(num_link*sizeof(long int));
			long int *link_costs=(long int *)malloc(num_link*sizeof(long int));
			get_links_from_adj_matrix(adj_matrix, map_element , links, link_costs, source);

			struct hashtb_enumerator ee;
			struct hashtb_enumerator *e = &ee;
			for (hashtb_start(nlsr->rev_map, e); e->key != NULL; hashtb_next(e)) 
			{
				struct map_entry *me=e->data;
				if ( me->mapping != source )
				{
					long int *faces=(long int *)calloc(num_link,sizeof(long int));
					double *nbr_dist=(double *)calloc(num_link,sizeof(double));
					double *nbr_to_dest=(double *)calloc(num_link,sizeof(double));
					for ( i=0 ; i < num_link; i++)
					{
						int face=get_next_hop_face_from_adl(get_router_from_rev_map(links[i]));
						double dist_to_nbr=get_hyperbolic_distance(source,links[i]);
						double dist_to_dest_from_nbr=get_hyperbolic_distance(links[i],me->mapping);
						faces[i]=face;
						nbr_dist[i]=dist_to_nbr;
						nbr_to_dest[i]=	dist_to_dest_from_nbr;	

						
					}
					sort_hyperbolic_route(nbr_to_dest,nbr_dist, faces,0,num_link);
					if (nlsr->max_faces_per_prefix == 0 )
					{
						for ( i=0 ; i < num_link; i++)
						{
							update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
						}				
					}
					else if ( nlsr->max_faces_per_prefix > 0 )
					{
						if ( num_link <= nlsr->max_faces_per_prefix )
						{
							for ( i=0 ; i < num_link; i++)
							{
								update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
							}
						}
						else if (num_link > nlsr->max_faces_per_prefix)
						{
							for ( i=0 ; i < nlsr->max_faces_per_prefix; i++)
							{
								update_routing_table_with_new_hyperbolic_route(me->mapping,faces[i],nbr_to_dest[i]);
							}
						}

					}
					free(faces);
					free(nbr_dist);
					free(nbr_to_dest);
				}
			}
			hashtb_end(e);

			
			free(links);
			free(link_costs);
		}
		else if (nlsr->is_hyperbolic_calc == 0 )
		{

			long int *parent=(long int *)malloc(map_element * sizeof(long int));
			long int *dist=(long int *)malloc(map_element * sizeof(long int));
			
		
			if ( (num_link == 0) || (nlsr->max_faces_per_prefix == 1 ) )
			{	
				calculate_path(adj_matrix,parent,dist, map_element, source);		
				print_all_path_from_source(parent,source);
				print_all_next_hop(parent,source);		
				update_routing_table_with_new_route(parent, dist,source);
			}
			else if ( (num_link != 0) && (nlsr->max_faces_per_prefix == 0 || nlsr->max_faces_per_prefix > 1 ) )
			{
				long int *links=(long int *)malloc(num_link*sizeof(long int));
				long int *link_costs=(long int *)malloc(num_link*sizeof(long int));
				get_links_from_adj_matrix(adj_matrix, map_element , links, link_costs, source);
				for ( i=0 ; i < num_link; i++)
				{
					adjust_adj_matrix(adj_matrix, map_element,source,links[i],link_costs[i]);
					calculate_path(adj_matrix,parent,dist, map_element, source);		
					print_all_path_from_source(parent,source);
					print_all_next_hop(parent,source);		
					update_routing_table_with_new_route(parent, dist,source);
				}

				free(links);
				free(link_costs);
			}
			free(parent);
			free(dist);
		}
		
		print_routing_table();
		print_npt();

		update_npt_with_new_route();

		print_routing_table();
		print_npt();


		for(i = 0; i < map_element; i++)
		{
			free(adj_matrix[i]);
		}
		
		free(adj_matrix);
		destroy_map();
		destroy_rev_map();
		//hashtb_destroy(&nlsr->map);
		//hashtb_destroy(&nlsr->rev_map);
		
	}
	nlsr->is_route_calculation_scheduled=0;

	nlsr_unlock();

	return 0;
}

void 
calculate_path(int **adj_matrix, long int *parent,long int *dist ,long int V, long int S)
{
	int i;
	long int v,u;
	//long int *dist=(long int *)malloc(V * sizeof(long int));
	long int *Q=(long int *)malloc(V * sizeof(long int));
	long int head=0;
	/* Initiate the Parent */
	for (i = 0 ; i < V; i++)
	{
		parent[i]=EMPTY_PARENT;
		dist[i]=INF_DISTANCE;
		Q[i]=i;
	} 

	if ( S != NO_MAPPING_NUM )
	{
		dist[S]=0;
		sort_queue_by_distance(Q,dist,head,V);

		while (head < V )
		{
			u=Q[head];
			if(dist[u] == INF_DISTANCE)
			{
				break;
			}

			for(v=0 ; v <V; v++)
			{
				if( adj_matrix[u][v] > 0 ) //
				{
					if ( is_not_explored(Q,v,head+1,V) )
					{
					
						if( dist[u] + adj_matrix[u][v] <  dist[v])
						{
							dist[v]=dist[u] + adj_matrix[u][v] ;
							parent[v]=u;
						}	

					}

				}

			}

			head++;
			sort_queue_by_distance(Q,dist,head,V);
		}
	}
	free(Q);	
}

void
print_all_path_from_source(long int *parent,long int source)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	if ( source != NO_MAPPING_NUM)
	{
		for(i=0;i<map_element;i++)
		{
			me=e->data;
			if(me->mapping != source)
			{
				
				if ( nlsr->debugging )
				{
					print_path(parent,(long int)me->mapping);
					printf("\n");
				}
				if ( nlsr->detailed_logging )
				{
					print_path(parent,(long int)me->mapping);
					writeLogg(__FILE__,__FUNCTION__,__LINE__,"\n");
				}
				
			}
			hashtb_next(e);		
		}
	}
	hashtb_end(e);

}

void 
print_all_next_hop(long int *parent,long int source)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		if(me->mapping != source)
		{
			if ( nlsr->debugging )
				printf("Dest: %d Next Hop: %ld\n",me->mapping,get_next_hop_from_calculation(parent,me->mapping,source));
			if ( nlsr->detailed_logging )
				writeLogg(__FILE__,__FUNCTION__,__LINE__,"Dest: %d Next Hop: %ld\n",me->mapping,get_next_hop_from_calculation(parent,me->mapping,source));
		}
		hashtb_next(e);		
	}

	hashtb_end(e);

}

long int
get_next_hop_from_calculation(long int *parent, long int dest,long int source)
{
	long int next_hop;
	while ( parent[dest] != EMPTY_PARENT )
	{
		next_hop=dest;
		dest=parent[dest];

	}

	if ( dest != source )
	{
		next_hop=NO_NEXT_HOP;	
	}
	
	return next_hop;
	
}

void
print_path(long int *parent, long int dest)
{
	if (parent[dest] != EMPTY_PARENT )
		print_path(parent,parent[dest]);

	if ( nlsr->debugging )
		printf(" %ld",dest);
}

int 
is_not_explored(long int *Q, long int u,long int start, long int element)
{
	int ret=0;
	long int i;
	for(i=start; i< element; i++)
	{
		if ( Q[i] == u )
		{
			ret=1;
			break;
		}
	}
	return ret;
}

void 
sort_queue_by_distance(long int *Q,long int *dist,long int start,long int element)
{
	long int i,j;
	long int temp_u;

	for ( i=start ; i < element ; i ++) 
	{
		for( j=i+1; j<element; j ++)
		{
			if (dist[Q[j]] < dist[Q[i]])
			{
				temp_u=Q[j];
				Q[j]=Q[i];
				Q[i]=temp_u;
			}
		}
	}
	
}

void 
sort_hyperbolic_route(double *dist_dest,double *dist_nbr, long int *faces,long int start,long int element)
{
	long int i,j;
	double temp_dist;
	long int temp_face;

	for ( i=start ; i < element ; i ++) 
	{
		for( j=i+1; j<element; j ++)
		{
			if (dist_dest[i] < dist_dest[j])
			{
				temp_dist=dist_dest[j];
				dist_dest[j]=dist_dest[i];
				dist_dest[i]=temp_dist;

				temp_dist=dist_nbr[j];
				dist_nbr[j]=dist_nbr[i];
				dist_nbr[i]=temp_dist;

				temp_face=faces[j];
				faces[j]=faces[i];
				faces[i]=temp_face;
			}
			if ( (dist_dest[i] == dist_dest[j]) && (dist_nbr[i] < dist_nbr[j]) )
			{
				temp_dist=dist_dest[j];
				dist_dest[j]=dist_dest[i];
				dist_dest[i]=temp_dist;

				temp_dist=dist_nbr[j];
				dist_nbr[j]=dist_nbr[i];
				dist_nbr[i]=temp_dist;

				temp_face=faces[j];
				faces[j]=faces[i];
				faces[i]=temp_face;
			}
		}
	}
	
}

void
print_map(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		if ( nlsr->debugging )
			printf("Router: %s Mapping Number: %d \n",me->router,me->mapping);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__,"Router: %s Mapping Number: %d \n",me->router,me->mapping);
		hashtb_next(e);		
	}

	hashtb_end(e);
}


void
assign_mapping_number(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		me->mapping=i;
		add_rev_map_entry(i,me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);
}

void 
make_map(void)
{
	

	int i, adj_lsdb_element;
	struct alsa *adj_lsa;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->lsdb->adj_lsdb, e);
	adj_lsdb_element=hashtb_n(nlsr->lsdb->adj_lsdb);

	add_map_entry(nlsr->router_name);

	for(i=0;i<adj_lsdb_element;i++)
	{
		adj_lsa=e->data;
		add_adj_data_to_map(adj_lsa->header->orig_router->name,adj_lsa->body,adj_lsa->no_link);
		hashtb_next(e);		
	}

	hashtb_end(e);

}

void 
add_map_entry(char *router)
{

	struct map_entry *me=(struct map_entry*)malloc(sizeof(struct map_entry ));

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;

   	hashtb_start(nlsr->map, e);
    	res = hashtb_seek(e, router, strlen(router), 0);

	if(res == HT_NEW_ENTRY)
	{
		me=e->data;
		me->router=(char *)malloc(strlen(router)+1);
		memset(me->router,0,strlen(router)+1);
		memcpy(me->router,router,strlen(router));
		me->mapping=0;
	}

	hashtb_end(e);
	
}


void 
add_adj_data_to_map(char *orig_router, char *body, int no_link)
{
	add_map_entry(orig_router);
	
	int i=0;
	char *lsa_data=(char *)malloc(strlen(body)+1);
	memset(	lsa_data,0,strlen(body)+1);
	memcpy(lsa_data,body,strlen(body)+1);
	char *sep="|";
	char *rem;
	char *rtr_id;
	char *length;
	//char *face;
	char *metric;
	
	if(no_link >0 )
	{
		rtr_id=strtok_r(lsa_data,sep,&rem);
		length=strtok_r(NULL,sep,&rem);
		//face=strtok_r(NULL,sep,&rem);
		metric=strtok_r(NULL,sep,&rem);

		if ( !nlsr->debugging && nlsr->debugging)
		{
			printf("Metric: %s Length:%s\n",metric,length);
		}
		add_map_entry(rtr_id);

		for(i=1;i<no_link;i++)
		{
			rtr_id=strtok_r(NULL,sep,&rem);
			length=strtok_r(NULL,sep,&rem);
			//face=strtok_r(NULL,sep,&rem);
			metric=strtok_r(NULL,sep,&rem);
			if ( !nlsr->debugging && nlsr->debugging)
			{
				printf("Metric: %s Length:%s\n",metric,length);
			}

			add_map_entry(rtr_id);

		}
	}
	
	free(lsa_data);
}

int 
get_mapping_no(char *router)
{
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;
	int ret;

	int n = hashtb_n(nlsr->map);

	if ( n < 1)
	{
		return NO_MAPPING_NUM;
	}

   	hashtb_start(nlsr->map, e);
    	res = hashtb_seek(e, router, strlen(router), 0);

	if( res == HT_OLD_ENTRY )
	{
		me=e->data;
		ret=me->mapping;
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		ret=NO_MAPPING_NUM;
	}

	hashtb_end(e);	

	return ret;

}


void 
add_rev_map_entry(long int mapping_number, char *router)
{

	struct map_entry *me=(struct map_entry*)malloc(sizeof(struct map_entry ));

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;

   	hashtb_start(nlsr->rev_map, e);
    	res = hashtb_seek(e, &mapping_number, sizeof(mapping_number), 0);

	if(res == HT_NEW_ENTRY)
	{
		me=e->data;
		me->router=(char *)malloc(strlen(router)+1);
		memset(me->router,0,strlen(router)+1);
		memcpy(me->router,router,strlen(router));
		me->mapping=mapping_number;
	}

	hashtb_end(e);
	
}



char * 
get_router_from_rev_map(long int mapping_number)
{

	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;

   	hashtb_start(nlsr->rev_map, e);
    	res = hashtb_seek(e, &mapping_number, sizeof(mapping_number), 0);

	if(res == HT_OLD_ENTRY)
	{
		me=e->data;
		hashtb_end(e);
		return me->router;
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		hashtb_end(e);
	}
	
	return NULL;
}

void
print_rev_map(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		if ( nlsr->debugging )
			printf("Mapping Number: %d Router: %s  \n",me->mapping,me->router);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__,"Mapping Number: %d Router: %s  \n",me->mapping,me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);
}


void
assign_adj_matrix_for_lsa(struct alsa *adj_lsa, int **adj_matrix)
{
	int mapping_orig_router=get_mapping_no(adj_lsa->header->orig_router->name);
	int mapping_nbr_router;

	int i;
	char *lsa_data=(char *)malloc(strlen(adj_lsa->body)+1);
	memset(	lsa_data,0,strlen(adj_lsa->body)+1);
	memcpy(lsa_data,adj_lsa->body,strlen(adj_lsa->body)+1);
	char *sep="|";
	char *rem;
	char *rtr_id;
	char *length;
	//char *face;
	char *metric;
	
	if(adj_lsa->no_link >0 )
	{
		rtr_id=strtok_r(lsa_data,sep,&rem);
		length=strtok_r(NULL,sep,&rem);
		//face=strtok_r(NULL,sep,&rem);
		metric=strtok_r(NULL,sep,&rem);
	
		if ( !nlsr->debugging && nlsr->debugging)
		{
				printf("Metric: %s Length:%s\n",metric,length);
		}

		mapping_nbr_router=get_mapping_no(rtr_id);
		adj_matrix[mapping_orig_router][mapping_nbr_router]=atoi(metric);

		for(i=1;i<adj_lsa->no_link;i++)
		{
			rtr_id=strtok_r(NULL,sep,&rem);
			length=strtok_r(NULL,sep,&rem);
			//face=strtok_r(NULL,sep,&rem);
			metric=strtok_r(NULL,sep,&rem);

			if ( !nlsr->debugging && nlsr->debugging)
			{
				printf("Metric: %s Length:%s\n",metric,length);
			}

			mapping_nbr_router=get_mapping_no(rtr_id);
			adj_matrix[mapping_orig_router][mapping_nbr_router]=atoi(metric);

		}
	}
	
	free(lsa_data);
}

void 
make_adj_matrix(int **adj_matrix,int map_element)
{

	init_adj_matrix(adj_matrix,map_element);

	int i, adj_lsdb_element;
	struct alsa *adj_lsa;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->lsdb->adj_lsdb, e);
	adj_lsdb_element=hashtb_n(nlsr->lsdb->adj_lsdb);

	for(i=0;i<adj_lsdb_element;i++)
	{
		adj_lsa=e->data;
		assign_adj_matrix_for_lsa(adj_lsa,adj_matrix);
		hashtb_next(e);		
	}

	hashtb_end(e);

}

void 
init_adj_matrix(int **adj_matrix,int map_element)
{
	int i, j;
	for(i=0;i<map_element;i++)
		for(j=0;j<map_element;j++)
			adj_matrix[i][j]=0;
}

void print_adj_matrix(int **adj_matrix, int map_element)
{
	int i, j;
	for(i=0;i<map_element;i++)
	{
		for(j=0;j<map_element;j++)
			printf("%d ",adj_matrix[i][j]);
		printf("\n");
	}
}


int 
get_no_link_from_adj_matrix(int **adj_matrix,long int V, long int S)
{
	int no_link=0;
	int i;

	for(i=0;i<V;i++)
	{	
		if ( adj_matrix[S][i] > 0 )
		{
			no_link++;
		}
	}
	return no_link;
}

void 
get_links_from_adj_matrix(int **adj_matrix, long int V ,long int *links, long int *link_costs,long int S)
{
	int i,j;
	j=0;
	for (i=0; i <V; i++)
	{
		if ( adj_matrix[S][i] > 0 )
		{
			links[j]=i;
			link_costs[j]=adj_matrix[S][i];
			j++;
		}
	}
}

void adjust_adj_matrix(int **adj_matrix, long int V, long int S, long int link,long int link_cost)
{
	int i;
	for ( i = 0; i < V; i++ )
	{
		if ( i == link )
		{
			adj_matrix[S][i]=link_cost;
		}
		else 
		{
			adj_matrix[S][i]=0;
		}
	}

}

int 
get_number_of_next_hop(char *dest_router)
{
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res,ret;

   	hashtb_start(nlsr->routing_table, e);
    	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;
		ret=hashtb_n(rte->face_list);
		//nhl=rte->face_list;
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		ret=NO_NEXT_HOP;
	}

	hashtb_end(e);	

	return ret;
}


int 
get_next_hop(char *dest_router,int *faces, int *route_costs)
{
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res,ret;

   	hashtb_start(nlsr->routing_table, e);
    	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;
		ret=hashtb_n(rte->face_list);
		//nhl=rte->face_list;
		int j,face_list_element;
		struct face_list_entry *fle;

		struct hashtb_enumerator eef;
    		struct hashtb_enumerator *ef = &eef;
    	
    		hashtb_start(rte->face_list, ef);
		face_list_element=hashtb_n(rte->face_list);
		for(j=0;j<face_list_element;j++)
		{
			fle=ef->data;
			//printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
			faces[j]=fle->next_hop_face;
			route_costs[j]=fle->route_cost;
			hashtb_next(ef);	
		}
		hashtb_end(ef);
		
	}
	else if(res == HT_NEW_ENTRY)
	{
		hashtb_delete(e);
		ret=NO_NEXT_HOP;
	}

	hashtb_end(e);	

	return ret;
}

void
add_next_hop_router(char *dest_router)
{
	if ( strcmp(dest_router,nlsr->router_name)== 0)
	{
		return ;
	}

	struct routing_table_entry *rte=(struct routing_table_entry *)malloc(sizeof(struct routing_table_entry));

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee; 	
    	int res;

   	hashtb_start(nlsr->routing_table, e);
    	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_NEW_ENTRY )
	{
		rte=e->data;
		rte->dest_router=(char *)malloc(strlen(dest_router)+1);
		memset(rte->dest_router,0,strlen(dest_router)+1);
		memcpy(rte->dest_router,dest_router,strlen(dest_router));
		//rte->next_hop_face=NO_NEXT_HOP;
		struct hashtb_param param_fle = {0};
		rte->face_list=hashtb_create(sizeof(struct face_list_entry), &param_fle);

		add_npt_entry(dest_router, dest_router, 0, NULL, NULL);
	}
	hashtb_end(e);

}

void 
add_next_hop_from_lsa_adj_body(char *body, int no_link)
{

	int i=0;
	char *lsa_data=(char *)malloc(strlen(body)+1);
	memset(	lsa_data,0,strlen(body)+1);
	memcpy(lsa_data,body,strlen(body)+1);
	char *sep="|";
	char *rem;
	char *rtr_id;
	char *length;
	//char *face;
	char *metric;

	if(no_link >0 )
	{
		rtr_id=strtok_r(lsa_data,sep,&rem);
		length=strtok_r(NULL,sep,&rem);
		//face=strtok_r(NULL,sep,&rem);
		metric=strtok_r(NULL,sep,&rem);
		if ( !nlsr->debugging && nlsr->debugging)
		{
			printf("Metric: %s Length:%s\n",metric,length);
		}


		add_next_hop_router(rtr_id);

		for(i=1;i<no_link;i++)
		{
			rtr_id=strtok_r(NULL,sep,&rem);
			length=strtok_r(NULL,sep,&rem);
			//face=strtok_r(NULL,sep,&rem);
			metric=strtok_r(NULL,sep,&rem);
			if ( !nlsr->debugging && nlsr->debugging)
			{
				printf("Metric: %s Length:%s\n",metric,length);
			}

			add_next_hop_router(rtr_id);
	
		}
	}

	free(lsa_data);


}

void 
update_routing_table(char * dest_router,int next_hop_face, int route_cost)
{
	if ( nlsr->debugging )
	{
		printf("update_routing_table called \n");
		printf("Dest Router: %s Next Hop face: %d Route Cost: %d \n",dest_router,next_hop_face,route_cost);
	}

	int res,res1;
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;

		struct hashtb_enumerator eef;
    		struct hashtb_enumerator *ef = &eef;
    	
    		hashtb_start(rte->face_list, ef);
		res1 = hashtb_seek(ef, &next_hop_face, sizeof(next_hop_face), 0);	
		if( res1 == HT_NEW_ENTRY)
		{
			struct face_list_entry *fle=(struct face_list_entry *)malloc(sizeof(struct face_list_entry));
			fle=ef->data;
			fle->next_hop_face=next_hop_face;
			fle->route_cost=route_cost;						
		}
		else if ( res1 == HT_OLD_ENTRY )
		{
			struct face_list_entry *fle;
			fle=ef->data;
			fle->route_cost=route_cost;
		}
		hashtb_end(ef);
	}
	else if ( res == HT_NEW_ENTRY )
	{
		hashtb_delete(e);
	}
	
	hashtb_end(e);
	
}

void 
print_routing_table(void)
{
	if ( nlsr->debugging )
		printf("print_routing_table called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"print_routing_table called\n");
	int i,j, rt_element,face_list_element;
	
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);

	for(i=0;i<rt_element;i++)
	{
		if ( nlsr->debugging )
			printf("----------Routing Table Entry %d------------------\n",i+1);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__,"----------Routing Table Entry %d------------------\n",i+1);
		
		rte=e->data;

		if ( nlsr->debugging )
			printf(" Destination Router: %s \n",rte->dest_router);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__," Destination Router: %s \n",rte->dest_router);

		
		//rte->next_hop_face == NO_NEXT_HOP ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", rte->next_hop_face);

		struct face_list_entry *fle;

		struct hashtb_enumerator eef;
    		struct hashtb_enumerator *ef = &eef;
    	
    		hashtb_start(rte->face_list, ef);
		face_list_element=hashtb_n(rte->face_list);
		if ( face_list_element <= 0 )
		{
			if ( nlsr->debugging )
				printf(" 	Face: No Face \n");
			if ( nlsr->detailed_logging )
				writeLogg(__FILE__,__FUNCTION__,__LINE__," 	Face: No Face \n");
		}
		else
		{
			for(j=0;j<face_list_element;j++)
			{
				fle=ef->data;
				if ( nlsr->debugging )
					printf(" 	Face: %d Route_Cost: %f \n",fle->next_hop_face,fle->route_cost);
				if ( nlsr->detailed_logging )
					writeLogg(__FILE__,__FUNCTION__,__LINE__," 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
				hashtb_next(ef);	
			}
		}
		hashtb_end(ef);

		hashtb_next(e);		
	}

	hashtb_end(e);

	if ( nlsr->debugging )
		printf("\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"\n");
}

/*
int
delete_empty_rte(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags)
{
	if ( nlsr->debugging )
	{
		printf("delete_empty_rte called\n");
		printf("Router: %s \n",(char *)ev->evdata);
	}
	if ( nlsr->detailed_logging )
	{
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"delete_empty_rte called\n");
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"Router: %s \n",(char *)ev->evdata);
	}
	
	if(flags == CCN_SCHEDULE_CANCEL)
	{
 	 	return -1;
	}

	nlsr_lock();
	int res;
	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	res = hashtb_seek(e, (char *)ev->evdata, strlen((char *)ev->evdata), 0);
	
	if ( res == HT_OLD_ENTRY )
	{
		hashtb_delete(e);
	}
	else if ( res == HT_NEW_ENTRY )
	{
		hashtb_delete(e);
	}

	print_routing_table();

	nlsr_unlock();
	
	return 0;
}
*/

void 
clear_old_routing_table(void)
{
	if ( nlsr->debugging )
		printf("clear_old_routing_table called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"clear_old_routing_table called\n");
	int i,rt_element;
	
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);

	for(i=0;i<rt_element;i++)
	{
		rte=e->data;
		hashtb_destroy(&rte->face_list);
		struct hashtb_param param_fle = {0};
		rte->face_list=hashtb_create(sizeof(struct face_list_entry), &param_fle);

		hashtb_next(e);		
	}

	hashtb_end(e);	
}


void 
do_old_routing_table_updates(void)
{
	if ( nlsr->debugging )
		printf("do_old_routing_table_updates called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"do_old_routing_table_updates called\n");
	
	int i, rt_element;
	int mapping_no;	

	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);

	for(i=0;i<rt_element;i++)
	{
		rte=e->data;
		mapping_no=get_mapping_no(rte->dest_router);
		if ( mapping_no == NO_MAPPING_NUM)
		{		
			delete_orig_router_from_npt(rte->dest_router);
			/*
			char *router=(char *)malloc(strlen(rte->dest_router)+1);
			memset(router,0,strlen(rte->dest_router)+1);
			memcpy(router,rte->dest_router,strlen(rte->dest_router)+1);
			nlsr->event = ccn_schedule_event(nlsr->sched, 1, &delete_empty_rte, (void *)router , 0);
			*/
			destroy_routing_table_entry_comp(rte);
			hashtb_delete(e);
			i++;
		}
		else
		{
			hashtb_next(e);
		}		
	}

	hashtb_end(e);	
}

void 
update_routing_table_with_new_hyperbolic_route(long int dest_router_rev_map_index, long int face, double nbr_to_dest_dist)
{
	if ( nlsr->debugging )
		printf("update_routing_table_with_new_hyperbolic_route called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"update_routing_table_with_new_hyperbolic_route called\n");
	
	char *orig_router=get_router_from_rev_map(dest_router_rev_map_index);

	if (face != NO_NEXT_HOP && face != NO_FACE )
	{
		update_routing_table(orig_router,face,nbr_to_dest_dist);
		if ( nlsr->debugging )
			printf ("Orig_router: %s Next Hop Face: %ld \n",orig_router,face);
		if ( nlsr->detailed_logging )
			writeLogg(__FILE__,__FUNCTION__,__LINE__,"Orig_router: %s Next Hop Face: %ld \n",orig_router,face);
					
	}
	

}


void 
update_routing_table_with_new_route(long int *parent, long int *dist,long int source)
{
	if ( nlsr->debugging )
		printf("update_routing_table_with_new_route called\n");
	if ( nlsr->detailed_logging )
		writeLogg(__FILE__,__FUNCTION__,__LINE__,"update_routing_table_with_new_route called\n");
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->rev_map, e);
	map_element=hashtb_n(nlsr->rev_map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		if(me->mapping != source)
		{
			
			char *orig_router=get_router_from_rev_map(me->mapping);
			if (orig_router != NULL )
			{
				int next_hop_router_num=get_next_hop_from_calculation(parent,me->mapping,source);
				if ( next_hop_router_num == NO_NEXT_HOP )
				{
					if ( nlsr->debugging )
						printf ("Orig_router: %s Next Hop Face: %d \n",orig_router,NO_FACE);
					if ( nlsr->detailed_logging )
						writeLogg(__FILE__,__FUNCTION__,__LINE__,"Orig_router: %s Next Hop Face: %d \n",orig_router,NO_FACE);
				}
				else 
				{
					char *next_hop_router=get_router_from_rev_map(next_hop_router_num);
					int next_hop_face=get_next_hop_face_from_adl(next_hop_router);
					update_routing_table(orig_router,next_hop_face,dist[me->mapping]);
					if ( nlsr->debugging )
						printf ("Orig_router: %s Next Hop Face: %d \n",orig_router,next_hop_face);
					if ( nlsr->detailed_logging )
						writeLogg(__FILE__,__FUNCTION__,__LINE__,"Orig_router: %s Next Hop Face: %d \n",orig_router,next_hop_face);
					

				}
			}
		}
		hashtb_next(e);		
	}

	hashtb_end(e);
}

int 
does_face_exist_for_router(char *dest_router, int face_id)
{
	if (nlsr->debugging)
	{
		printf("does_face_exist_for_router called\n");
		printf("Dest Router: %s and Face id: %d \n",dest_router, face_id);
	}

	int ret=0;

	int res;
	struct routing_table_entry *rte;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->routing_table, e);
	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);

	if( res == HT_OLD_ENTRY )
	{
		rte=e->data;
		unsigned *v;
		v = hashtb_lookup(rte->face_list, &face_id, sizeof(face_id));
		if (v != NULL)
			ret = 1;
	}
	else
	{
		hashtb_delete(e);
	} 
	
	hashtb_end(e);

	return ret;
}

double 
get_hyperbolic_distance(long int source, long int dest)
{
	double distance;
	char *src_router=get_router_from_rev_map(source);
	char *dest_router=get_router_from_rev_map(dest);

	double src_r=get_hyperbolic_r(src_router);
	double src_theta=get_hyperbolic_r(src_router);	

	double dest_r=get_hyperbolic_r(dest_router);
	double dest_theta=get_hyperbolic_r(dest_router);
	if ( src_r != -1 && dest_r != -1 )
	{
		distance=acosh(cosh(src_r)*cosh(dest_r)-sinh(src_r)*sinh(dest_r)*cos(src_theta-dest_theta));
	}
	else 
	{
		distance= -1.0;
	}
	
	return distance;
}

void
destroy_routing_table_entry_comp(struct routing_table_entry *rte)
{

	free(rte->dest_router);
	hashtb_destroy(&rte->face_list);	
		
}

void
destroy_routing_table_entry(struct routing_table_entry *rte)
{

	destroy_routing_table_entry_comp(rte);
	free(rte);
}

void
destroy_routing_table(void)
{
	int i, rt_element;
	struct hashtb_enumerator ee;
	struct hashtb_enumerator *e = &ee;

	struct routing_table_entry *rte;
	hashtb_start(nlsr->routing_table, e);
	rt_element=hashtb_n(nlsr->routing_table);
	for(i=0;i<rt_element;i++)
	{
		rte=e->data;
		free(rte->dest_router);
		hashtb_destroy(&rte->face_list);	
		hashtb_next(e);		
	}	
	hashtb_end(e);
	hashtb_destroy(&nlsr->routing_table);

}

void
destroy_map(void)
{

	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->map, e);
	map_element=hashtb_n(nlsr->map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		free(me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);

}

void
destroy_rev_map(void)
{
	int i, map_element;
	struct map_entry *me;

	struct hashtb_enumerator ee;
    	struct hashtb_enumerator *e = &ee;
    	
    	hashtb_start(nlsr->rev_map, e);
	map_element=hashtb_n(nlsr->rev_map);

	for(i=0;i<map_element;i++)
	{
		me=e->data;
		free(me->router);
		hashtb_next(e);		
	}

	hashtb_end(e);
}
